libcamera: controls: Generate and use fixed-sized Span types

Define Span types explicitly as either variable- or fixed-sized. This
introduces a new convention for defining Span dimensions in the property
and control value definitions and generates Span types as variable-sized
Span<T> or as fixed-sized Span<T,N>.

Signed-off-by: Christian Rauch <Rauch.Christian@gmx.de>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
Christian Rauch 2022-08-02 23:03:24 +02:00 committed by Laurent Pinchart
parent 293e23e21c
commit 09c1b081ba
6 changed files with 38 additions and 25 deletions

View file

@ -168,7 +168,7 @@ public:
using V = typename T::value_type; using V = typename T::value_type;
const V *value = reinterpret_cast<const V *>(data().data()); const V *value = reinterpret_cast<const V *>(data().data());
return { value, numElements_ }; return T{ value, numElements_ };
} }
#ifndef __DOXYGEN__ #ifndef __DOXYGEN__

View file

@ -567,18 +567,19 @@ void IPARPi::reportMetadata()
AwbStatus *awbStatus = rpiMetadata_.getLocked<AwbStatus>("awb.status"); AwbStatus *awbStatus = rpiMetadata_.getLocked<AwbStatus>("awb.status");
if (awbStatus) { if (awbStatus) {
libcameraMetadata_.set(controls::ColourGains, { static_cast<float>(awbStatus->gainR), libcameraMetadata_.set(controls::ColourGains,
static_cast<float>(awbStatus->gainB) }); Span<const float, 2>({ static_cast<float>(awbStatus->gainR),
static_cast<float>(awbStatus->gainB) }));
libcameraMetadata_.set(controls::ColourTemperature, awbStatus->temperatureK); libcameraMetadata_.set(controls::ColourTemperature, awbStatus->temperatureK);
} }
BlackLevelStatus *blackLevelStatus = rpiMetadata_.getLocked<BlackLevelStatus>("black_level.status"); BlackLevelStatus *blackLevelStatus = rpiMetadata_.getLocked<BlackLevelStatus>("black_level.status");
if (blackLevelStatus) if (blackLevelStatus)
libcameraMetadata_.set(controls::SensorBlackLevels, libcameraMetadata_.set(controls::SensorBlackLevels,
{ static_cast<int32_t>(blackLevelStatus->blackLevelR), Span<const int32_t, 4>({ static_cast<int32_t>(blackLevelStatus->blackLevelR),
static_cast<int32_t>(blackLevelStatus->blackLevelG), static_cast<int32_t>(blackLevelStatus->blackLevelG),
static_cast<int32_t>(blackLevelStatus->blackLevelG), static_cast<int32_t>(blackLevelStatus->blackLevelG),
static_cast<int32_t>(blackLevelStatus->blackLevelB) }); static_cast<int32_t>(blackLevelStatus->blackLevelB) }));
FocusStatus *focusStatus = rpiMetadata_.getLocked<FocusStatus>("focus.status"); FocusStatus *focusStatus = rpiMetadata_.getLocked<FocusStatus>("focus.status");
if (focusStatus && focusStatus->num == 12) { if (focusStatus && focusStatus->num == 12) {
@ -883,7 +884,7 @@ void IPARPi::queueRequest(const ControlList &controls)
if (gains[0] != 0.0f && gains[1] != 0.0f) if (gains[0] != 0.0f && gains[1] != 0.0f)
/* A gain of 0.0f will switch back to auto mode. */ /* A gain of 0.0f will switch back to auto mode. */
libcameraMetadata_.set(controls::ColourGains, libcameraMetadata_.set(controls::ColourGains,
{ gains[0], gains[1] }); Span<const float, 2>({ gains[0], gains[1] }));
break; break;
} }
@ -1167,8 +1168,8 @@ void IPARPi::applyFrameDurations(Duration minFrameDuration, Duration maxFrameDur
/* Return the validated limits via metadata. */ /* Return the validated limits via metadata. */
libcameraMetadata_.set(controls::FrameDurationLimits, libcameraMetadata_.set(controls::FrameDurationLimits,
{ static_cast<int64_t>(minFrameDuration_.get<std::micro>()), Span<const int64_t, 2>({ static_cast<int64_t>(minFrameDuration_.get<std::micro>()),
static_cast<int64_t>(maxFrameDuration_.get<std::micro>()) }); static_cast<int64_t>(maxFrameDuration_.get<std::micro>()) }));
/* /*
* Calculate the maximum exposure time possible for the AGC to use. * Calculate the maximum exposure time possible for the AGC to use.

View file

@ -291,7 +291,7 @@ controls:
transformation. The 3x3 matrix is stored in conventional reading transformation. The 3x3 matrix is stored in conventional reading
order in an array of 9 floating point values. order in an array of 9 floating point values.
size: [3x3] size: [3,3]
- ScalerCrop: - ScalerCrop:
type: Rectangle type: Rectangle
@ -525,7 +525,7 @@ controls:
the window where the focal distance for the objects shown in that part the window where the focal distance for the objects shown in that part
of the image are closest to the camera. of the image are closest to the camera.
size: [n] size: []
- AfTrigger: - AfTrigger:
type: int32_t type: int32_t

View file

@ -497,7 +497,7 @@ controls:
- PixelArrayOpticalBlackRectangles: - PixelArrayOpticalBlackRectangles:
type: Rectangle type: Rectangle
size: [n] size: []
description: | description: |
The pixel array region(s) which contain optical black pixels The pixel array region(s) which contain optical black pixels
considered valid for calibration purposes. considered valid for calibration purposes.
@ -592,7 +592,7 @@ controls:
- PixelArrayActiveAreas: - PixelArrayActiveAreas:
type: Rectangle type: Rectangle
size: [n] size: []
description: | description: |
The PixelArrayActiveAreas property defines the (possibly multiple and The PixelArrayActiveAreas property defines the (possibly multiple and
overlapping) portions of the camera sensor readable pixel matrix overlapping) portions of the camera sensor readable pixel matrix

View file

@ -517,7 +517,7 @@ int DNGWriter::write(const char *filename, const Camera *camera,
const auto &blackLevels = metadata.get(controls::SensorBlackLevels); const auto &blackLevels = metadata.get(controls::SensorBlackLevels);
if (blackLevels) { if (blackLevels) {
Span<const int32_t> levels = *blackLevels; Span<const int32_t, 4> levels = *blackLevels;
/* /*
* The black levels control is specified in R, Gr, Gb, B order. * The black levels control is specified in R, Gr, Gb, B order.

View file

@ -7,6 +7,8 @@
# gen-controls.py - Generate control definitions from YAML # gen-controls.py - Generate control definitions from YAML
import argparse import argparse
from functools import reduce
import operator
import string import string
import sys import sys
import yaml import yaml
@ -22,6 +24,24 @@ def format_description(description):
return '\n'.join([(line and ' * ' or ' *') + line for line in description]) return '\n'.join([(line and ' * ' or ' *') + line for line in description])
def get_ctrl_type(ctrl):
ctrl_type = ctrl['type']
ctrl_size_arr = ctrl.get('size')
if ctrl_type == 'string':
return 'std::string'
elif ctrl_size_arr is not None:
if len(ctrl_size_arr) > 0:
# fixed-sized Span
ctrl_span_size = reduce(operator.mul, ctrl_size_arr)
return f"Span<const {ctrl_type}, {ctrl_span_size}>"
else:
# variable-sized Span
return f"Span<const {ctrl_type}>"
else:
return ctrl_type
def generate_cpp(controls): def generate_cpp(controls):
enum_doc_start_template = string.Template('''/** enum_doc_start_template = string.Template('''/**
* \\enum ${name}Enum * \\enum ${name}Enum
@ -50,11 +70,7 @@ ${description}
name, ctrl = ctrl.popitem() name, ctrl = ctrl.popitem()
id_name = snake_case(name).upper() id_name = snake_case(name).upper()
ctrl_type = ctrl['type'] ctrl_type = get_ctrl_type(ctrl)
if ctrl_type == 'string':
ctrl_type = 'std::string'
elif ctrl.get('size'):
ctrl_type = 'Span<const %s>' % ctrl_type
info = { info = {
'name': name, 'name': name,
@ -135,11 +151,7 @@ def generate_h(controls):
ids.append('\t' + id_name + ' = ' + str(id_value) + ',') ids.append('\t' + id_name + ' = ' + str(id_value) + ',')
ctrl_type = ctrl['type'] ctrl_type = get_ctrl_type(ctrl)
if ctrl_type == 'string':
ctrl_type = 'std::string'
elif ctrl.get('size'):
ctrl_type = 'Span<const %s>' % ctrl_type
info = { info = {
'name': name, 'name': name,