libcamera: Extend u32 control type
V4L2 Controls support a wide variety of types not yet supported by the ControlValue type system. Extend the libcamera ControlValue types to support an explicit 32 bit unsigned integer type, and map that to the corresponding V4L2_CTRL_TYPE_U32 type within the v4l2_device support class. Signed-off-by: Yudhistira Erlandinata <yerlandinata@chromium.org> Co-developed-by: Harvey Yang <chenghaoyang@chromium.org> Signed-off-by: Harvey Yang <chenghaoyang@chromium.org> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
1197fff482
commit
86902b39d7
4 changed files with 91 additions and 7 deletions
|
@ -29,6 +29,7 @@ enum ControlType {
|
|||
ControlTypeNone,
|
||||
ControlTypeBool,
|
||||
ControlTypeByte,
|
||||
ControlTypeUnsigned32,
|
||||
ControlTypeInteger32,
|
||||
ControlTypeInteger64,
|
||||
ControlTypeFloat,
|
||||
|
@ -62,6 +63,12 @@ struct control_type<uint8_t> {
|
|||
static constexpr std::size_t size = 0;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct control_type<uint32_t> {
|
||||
static constexpr ControlType value = ControlTypeUnsigned32;
|
||||
static constexpr std::size_t size = 0;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct control_type<int32_t> {
|
||||
static constexpr ControlType value = ControlTypeInteger32;
|
||||
|
|
|
@ -54,6 +54,7 @@ static constexpr size_t ControlValueSize[] = {
|
|||
[ControlTypeNone] = 0,
|
||||
[ControlTypeBool] = sizeof(bool),
|
||||
[ControlTypeByte] = sizeof(uint8_t),
|
||||
[ControlTypeUnsigned32] = sizeof(uint32_t),
|
||||
[ControlTypeInteger32] = sizeof(int32_t),
|
||||
[ControlTypeInteger64] = sizeof(int64_t),
|
||||
[ControlTypeFloat] = sizeof(float),
|
||||
|
@ -74,10 +75,12 @@ static constexpr size_t ControlValueSize[] = {
|
|||
* The control stores a boolean value
|
||||
* \var ControlTypeByte
|
||||
* The control stores a byte value as an unsigned 8-bit integer
|
||||
* \var ControlTypeUnsigned32
|
||||
* The control stores an unsigned 32-bit integer value
|
||||
* \var ControlTypeInteger32
|
||||
* The control stores a 32-bit integer value
|
||||
* The control stores a signed 32-bit integer value
|
||||
* \var ControlTypeInteger64
|
||||
* The control stores a 64-bit integer value
|
||||
* The control stores a signed 64-bit integer value
|
||||
* \var ControlTypeFloat
|
||||
* The control stores a 32-bit floating point value
|
||||
* \var ControlTypeString
|
||||
|
@ -230,6 +233,11 @@ std::string ControlValue::toString() const
|
|||
str += std::to_string(*value);
|
||||
break;
|
||||
}
|
||||
case ControlTypeUnsigned32: {
|
||||
const uint32_t *value = reinterpret_cast<const uint32_t *>(data);
|
||||
str += std::to_string(*value);
|
||||
break;
|
||||
}
|
||||
case ControlTypeInteger32: {
|
||||
const int32_t *value = reinterpret_cast<const int32_t *>(data);
|
||||
str += std::to_string(*value);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <fcntl.h>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
@ -204,10 +205,22 @@ ControlList V4L2Device::getControls(const std::vector<uint32_t> &ids)
|
|||
|
||||
if (info.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) {
|
||||
ControlType type;
|
||||
ControlValue &value = ctrl.second;
|
||||
Span<uint8_t> data;
|
||||
|
||||
switch (info.type) {
|
||||
case V4L2_CTRL_TYPE_U8:
|
||||
type = ControlTypeByte;
|
||||
value.reserve(type, true, info.elems);
|
||||
data = value.data();
|
||||
v4l2Ctrl.p_u8 = data.data();
|
||||
break;
|
||||
|
||||
case V4L2_CTRL_TYPE_U32:
|
||||
type = ControlTypeUnsigned32;
|
||||
value.reserve(type, true, info.elems);
|
||||
data = value.data();
|
||||
v4l2Ctrl.p_u32 = reinterpret_cast<uint32_t *>(data.data());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -217,11 +230,6 @@ ControlList V4L2Device::getControls(const std::vector<uint32_t> &ids)
|
|||
return {};
|
||||
}
|
||||
|
||||
ControlValue &value = ctrl.second;
|
||||
value.reserve(type, true, info.elems);
|
||||
Span<uint8_t> data = value.data();
|
||||
|
||||
v4l2Ctrl.p_u8 = data.data();
|
||||
v4l2Ctrl.size = data.size();
|
||||
}
|
||||
}
|
||||
|
@ -299,6 +307,18 @@ int V4L2Device::setControls(ControlList *ctrls)
|
|||
/* Set the v4l2_ext_control value for the write operation. */
|
||||
ControlValue &value = ctrl->second;
|
||||
switch (iter->first->type()) {
|
||||
case ControlTypeUnsigned32: {
|
||||
if (value.isArray()) {
|
||||
Span<uint8_t> data = value.data();
|
||||
v4l2Ctrl.p_u32 = reinterpret_cast<uint32_t *>(data.data());
|
||||
v4l2Ctrl.size = data.size();
|
||||
} else {
|
||||
v4l2Ctrl.value = value.get<uint32_t>();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ControlTypeInteger32: {
|
||||
if (value.isArray()) {
|
||||
Span<uint8_t> data = value.data();
|
||||
|
@ -488,6 +508,9 @@ ControlType V4L2Device::v4l2CtrlType(uint32_t ctrlType)
|
|||
case V4L2_CTRL_TYPE_BOOLEAN:
|
||||
return ControlTypeBool;
|
||||
|
||||
case V4L2_CTRL_TYPE_U32:
|
||||
return ControlTypeUnsigned32;
|
||||
|
||||
case V4L2_CTRL_TYPE_INTEGER:
|
||||
return ControlTypeInteger32;
|
||||
|
||||
|
@ -536,6 +559,11 @@ std::optional<ControlInfo> V4L2Device::v4l2ControlInfo(const v4l2_query_ext_ctrl
|
|||
static_cast<uint8_t>(ctrl.maximum),
|
||||
static_cast<uint8_t>(ctrl.default_value));
|
||||
|
||||
case V4L2_CTRL_TYPE_U32:
|
||||
return ControlInfo(static_cast<uint32_t>(ctrl.minimum),
|
||||
static_cast<uint32_t>(ctrl.maximum),
|
||||
static_cast<uint32_t>(ctrl.default_value));
|
||||
|
||||
case V4L2_CTRL_TYPE_BOOLEAN:
|
||||
return ControlInfo(static_cast<bool>(ctrl.minimum),
|
||||
static_cast<bool>(ctrl.maximum),
|
||||
|
@ -622,6 +650,7 @@ void V4L2Device::listControls()
|
|||
case V4L2_CTRL_TYPE_BITMASK:
|
||||
case V4L2_CTRL_TYPE_INTEGER_MENU:
|
||||
case V4L2_CTRL_TYPE_U8:
|
||||
case V4L2_CTRL_TYPE_U32:
|
||||
break;
|
||||
/* \todo Support other control types. */
|
||||
default:
|
||||
|
|
|
@ -109,6 +109,46 @@ protected:
|
|||
return TestFail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unsigned Integer32 type.
|
||||
*/
|
||||
value.set(static_cast<uint32_t>(42));
|
||||
if (value.isNone() || value.isArray() ||
|
||||
value.type() != ControlTypeUnsigned32) {
|
||||
cerr << "Control type mismatch after setting to uint32_t" << endl;
|
||||
return TestFail;
|
||||
}
|
||||
|
||||
if (value.get<uint32_t>() != 42) {
|
||||
cerr << "Control value mismatch after setting to uint32_t" << endl;
|
||||
return TestFail;
|
||||
}
|
||||
|
||||
if (value.toString() != "42") {
|
||||
cerr << "Control string mismatch after setting to uint32_t" << endl;
|
||||
return TestFail;
|
||||
}
|
||||
|
||||
std::array<uint32_t, 4> uint32s{ 3, 14, 15, 9 };
|
||||
value.set(Span<uint32_t>(uint32s));
|
||||
if (value.isNone() || !value.isArray() ||
|
||||
value.type() != ControlTypeUnsigned32) {
|
||||
cerr << "Control type mismatch after setting to uint32_t array" << endl;
|
||||
return TestFail;
|
||||
}
|
||||
|
||||
Span<const uint32_t> uint32sResult = value.get<Span<const uint32_t>>();
|
||||
if (uint32s.size() != uint32sResult.size() ||
|
||||
!std::equal(uint32s.begin(), uint32s.end(), uint32sResult.begin())) {
|
||||
cerr << "Control value mismatch after setting to uint32_t array" << endl;
|
||||
return TestFail;
|
||||
}
|
||||
|
||||
if (value.toString() != "[ 3, 14, 15, 9 ]") {
|
||||
cerr << "Control string mismatch after setting to uint32_t array" << endl;
|
||||
return TestFail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Integer32 type.
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue