libcamera: control_serializer: store/load all ControlValue types

The min/max/def ControlValue of a ControlInfo can take arbitrary types that
are different from each other and different from the ControlId type.
The serialiser serialises these ControlValue separately by their type but
does not store the type. The deserialiser assumes that ControlValue types
match the ControlId type. If this is not the case, deserialisation will try
to deserialise values of the wrong type.

Fix this by serialising each of the min/max/def ControlValue's ControlType
and storing it just before the serialised ControlValue.

Fixes: https://bugs.libcamera.org/show_bug.cgi?id=137

Signed-off-by: Christian Rauch <Rauch.Christian@gmx.de>
Tested-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
This commit is contained in:
Christian Rauch 2022-09-03 23:33:29 +02:00 committed by Paul Elder
parent 560ceb1ea8
commit cbc2be34ed
2 changed files with 15 additions and 17 deletions

View file

@ -47,9 +47,9 @@ private:
static void store(const ControlValue &value, ByteStreamBuffer &buffer); static void store(const ControlValue &value, ByteStreamBuffer &buffer);
static void store(const ControlInfo &info, ByteStreamBuffer &buffer); static void store(const ControlInfo &info, ByteStreamBuffer &buffer);
ControlValue loadControlValue(ControlType type, ByteStreamBuffer &buffer, ControlValue loadControlValue(ByteStreamBuffer &buffer,
bool isArray = false, unsigned int count = 1); bool isArray = false, unsigned int count = 1);
ControlInfo loadControlInfo(ControlType type, ByteStreamBuffer &buffer); ControlInfo loadControlInfo(ByteStreamBuffer &buffer);
unsigned int serial_; unsigned int serial_;
unsigned int serialSeed_; unsigned int serialSeed_;

View file

@ -144,7 +144,7 @@ void ControlSerializer::reset()
size_t ControlSerializer::binarySize(const ControlValue &value) size_t ControlSerializer::binarySize(const ControlValue &value)
{ {
return value.data().size_bytes(); return sizeof(ControlType) + value.data().size_bytes();
} }
size_t ControlSerializer::binarySize(const ControlInfo &info) size_t ControlSerializer::binarySize(const ControlInfo &info)
@ -195,6 +195,8 @@ size_t ControlSerializer::binarySize(const ControlList &list)
void ControlSerializer::store(const ControlValue &value, void ControlSerializer::store(const ControlValue &value,
ByteStreamBuffer &buffer) ByteStreamBuffer &buffer)
{ {
const ControlType type = value.type();
buffer.write(&type);
buffer.write(value.data()); buffer.write(value.data());
} }
@ -379,11 +381,13 @@ int ControlSerializer::serialize(const ControlList &list,
return 0; return 0;
} }
ControlValue ControlSerializer::loadControlValue(ControlType type, ControlValue ControlSerializer::loadControlValue(ByteStreamBuffer &buffer,
ByteStreamBuffer &buffer,
bool isArray, bool isArray,
unsigned int count) unsigned int count)
{ {
ControlType type;
buffer.read(&type);
ControlValue value; ControlValue value;
value.reserve(type, isArray, count); value.reserve(type, isArray, count);
@ -392,15 +396,11 @@ ControlValue ControlSerializer::loadControlValue(ControlType type,
return value; return value;
} }
ControlInfo ControlSerializer::loadControlInfo(ControlType type, ControlInfo ControlSerializer::loadControlInfo(ByteStreamBuffer &b)
ByteStreamBuffer &b)
{ {
if (type == ControlTypeString) ControlValue min = loadControlValue(b);
type = ControlTypeInteger32; ControlValue max = loadControlValue(b);
ControlValue def = loadControlValue(b);
ControlValue min = loadControlValue(type, b);
ControlValue max = loadControlValue(type, b);
ControlValue def = loadControlValue(type, b);
return ControlInfo(min, max, def); return ControlInfo(min, max, def);
} }
@ -513,7 +513,7 @@ ControlInfoMap ControlSerializer::deserialize<ControlInfoMap>(ByteStreamBuffer &
} }
/* Create and store the ControlInfo. */ /* Create and store the ControlInfo. */
ctrls.emplace(controlId, loadControlInfo(type, values)); ctrls.emplace(controlId, loadControlInfo(values));
} }
/* /*
@ -624,10 +624,8 @@ ControlList ControlSerializer::deserialize<ControlList>(ByteStreamBuffer &buffer
return {}; return {};
} }
ControlType type = static_cast<ControlType>(entry->type);
ctrls.set(entry->id, ctrls.set(entry->id,
loadControlValue(type, values, entry->is_array, loadControlValue(values, entry->is_array, entry->count));
entry->count));
} }
return ctrls; return ctrls;