Commit Graph

26 Commits

Author SHA1 Message Date
Laurent Pinchart
496e4467d2 libcamera: control_serializer: Fix usage of uninitialized variable
The idMap variable may be used uninitialized in the
ControlSerializer::deserialize<ControlList>() function as reported by
gcc 11:

../../src/libcamera/control_serializer.cpp: In member function ‘T libcamera::ControlSerializer::deserialize(libcamera::ByteStreamBuffer&) [with T = libcamera::ControlList]’:
../../src/libcamera/control_serializer.cpp:609:33: error: ‘idMap’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  609 |         ControlList ctrls(*idMap);
      |

This is due to a missing default case in a switch/case. Fix it by adding
the default case.

Fixes: 6b1404fc4836 ("libcamera: control_serializer: Fix usage of uninitialized variable")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-09-28 00:43:57 +03:00
Jacopo Mondi
11e9d19288 libcamera: control_serializer: Separate the handles space
Two independent instances of the ControlSerializer class are in use at
the IPC boundaries, one in the Proxy class that serializes data from the
pipeline handler to the IPA, and one in the ProxyWorker which serializes
data in the opposite direction.

Each instance operates autonomously, without any centralized point of
control, and each one assigns a numerical handle to each ControlInfoMap
it serializes. This creates a risk of potential collision on the handle
values, as both instances will use the same numerical space and
are not aware of what handles has been already used by the instance "on
the other side".

To fix that, partition the handles numerical space by initializing the
control serializer with a seed according to the role of the component
that creates the serializer and increment the handle number by 2, to
avoid any collision risk.

While this is temporary and rather hacky solution, it solves an issue
with isolated IPA modules without too much complexity added.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-09-27 14:39:15 +02:00
Jacopo Mondi
23c2b8a9ca libcamera: control_serializer: Serialize info::def()
The ControlInfo class was originally designed to only transport
the control's minimum and maximum values which represent the control's
valid limits.

Later the default value of the control has been added to the ControlInfo
class, but the control serializer implementation has not been updated
accordingly.

This causes issues in IPA modules making use of ControlInfo::def() as,
when running in isolation, they would receive 0.

Fix that by serializing and deserializing the additional ControlValue
and update the protocol description accordingly.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-09-27 14:37:45 +02:00
Jacopo Mondi
b516ffb3bd libcamera: control_serializer: Use the right idmap
When a ControlList is deserialized, the code searches for a valid
ControlInfoMap in the local cache and use its id map to initialize the
list. If no valid ControlInfoMap is found, as it's usually the case
for lists transporting libcamera controls and properties, the globally
defined controls::controls id map is used unconditionally.

This breaks the deserialization of libcamera properties, for which a
wrong idmap is used at construction time.

As the serialization header now transports an id_map_type field, store
the idmap type at serialization time, and re-use it at
deserialization time to identify the correct id map.

Also make the validation stricter by imposing to list of V4L2 controls to
have an associated ControlInfoMap available, as there is no globally
defined idmap for such controls.

To be able to retrieve the idmap associated with a ControlList, add an
accessor function to the ControlList class.

It might be worth in future using a ControlInfoMap to initialize the
deserialized ControlList to implement controls validation against their
limit. As such validation is not implemented at the moment, maintain the
current behaviour and initialize the control list with an idmap.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-09-27 14:37:39 +02:00
Jacopo Mondi
62c82ab93f libcamera: controls: Use ControlIdMap in deserialization
Introduce a new field in the controls serialization protocol to
allow discerning which ControlIdMap a ControlInfoMap refers to.

The newly introduced IdMapType enumeration describes the possible
info maps:
- Either the globally available controls::controls and
  properties::properties maps, which are valid across IPC boundaries
- A ControlIdMap created locally by the V4L2 device, which is not valid
  across the IPC boundaries

At de-serialization time the idMapType field is inspected and
- If the idmap is a globally defined one, there's no need to create
  new ControlId instances when populating the de-serialized
  ControlInfoMap. Use the globally available map to retrieve the
  ControlId reference and use it.
- If the idmap is a map only available locally, create a new ControlId
  as it used to happen before this patch.

As a direct consequence, this change allows us to perform lookup by
ControlId reference on de-serialized ControlIdMap that refers to the
libcamera defined controls::controls and properties::properties.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-12 10:08:28 +02:00
Jacopo Mondi
b48db3c489 libcamera: controls: Create ControlInfoMap with ControlIdMap
ControlInfoMap does not have a ControlId map associated, but rather
creates one with the generateIdMap() function at creation time.

As a consequence, when in the need to de-serialize a ControlInfoMap all
the ControlId it contains are created by the deserializer instance, not
being able to discern if the controls the ControlIdMap refers to are the
global libcamera controls (and properties) or instances local to the
V4L2 device that has first initialized the controls.

As a consequence the ControlId stored in a de-serialized map will always
be newly created entities, preventing lookup by ControlId reference on a
de-serialized ControlInfoMap.

In order to make it possible to use globally available ControlId
instances whenever possible, create ControlInfoMap with a reference to
an externally allocated ControlIdMap instead of generating one
internally.

As a consequence the class constructors take and additional argument,
which might be not pleasant to type in, but enforces the concepts that
ControlInfoMap should be created with controls part of the same id map.

As the ControlIdMap the ControlInfoMap refers to needs to be allocated
externally:
- Use the globally available controls::controls (or
  properties::properties) id map when referring to libcamera controls
- The V4L2 device that creates ControlInfoMap by parsing the device's
  controls has to allocate a ControlIdMap
- The ControlSerializer that de-serializes a ControlInfoMap has to
  create and store the ControlIdMap the de-serialized info map refers to

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-12 10:06:25 +02:00
Laurent Pinchart
a48a000a33 libcamera: Rename 'method' to 'function'
Usage of 'method' to refer to member functions comes from Java. The C++
standard uses the term 'function' only. Replace 'method' with 'function'
or 'member function' through the whole code base and documentation.
While at it, fix two typos (s/backeng/backend/).

The BoundMethod and Object::invokeMethod() are left as-is here, and will
be addressed separately.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-08-09 15:40:32 +03:00
Kieran Bingham
b71e8c2f39 libcamera/base: Move span to base library
Move span, and adjust the Doxygen exclusion as well.

Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-06-25 16:11:11 +01:00
Kieran Bingham
27aff949fb libcamera/base: Move extended base functionality
Move the functionality for the following components to the new
base support library:

 - BoundMethod
 - EventDispatcher
 - EventDispatcherPoll
 - Log
 - Message
 - Object
 - Signal
 - Semaphore
 - Thread
 - Timer

While it would be preferable to see these split to move one component
per commit, these components are all interdependent upon each other,
which leaves us with one big change performing the move for all of them.

Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-06-25 16:11:08 +01:00
Paul Elder
892c0f4c19 libcamera: control_serializer: Save serialized ControlInfoMap in a cache
The ControlSerializer saves all ControlInfoMaps that it has already
(de)serialized, in order to (de)serialize ControlLists that contain the
ControlInfoMaps. Leverage this to cache ControlInfoMaps, such that the
ControlSerializer will not re-(de)serialize a ControlInfoMap that it has
previously (de)serialized.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-02-16 19:20:57 +09:00
Laurent Pinchart
f934fd1cb9 libcamera: Move IPA headers from include/ipa/ to include/libcamera/ipa/
The IPA headers are installed into $prefix/include/libcamera/ipa/, but
are located in the source tree in include/ipa/. This requires files
within libcamera to include them with

 #include <ipa/foo.h>

while a third party IPA would need to use

 #include <libcamera/ipa/foo.h>

Not only is this inconsistent, it can create issues later if IPA headers
need to include each other, as the first form of include directive
wouldn't be valid once the headers are installed.

Fix the problem by moving the IPA headers to include/libcamera/ipa/.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Jacopo Mondi <jacopo@jmondi.org>
2020-05-16 03:38:47 +03:00
Laurent Pinchart
93e72b695e libcamera: Move internal headers to include/libcamera/internal/
The libcamera internal headers are located in src/libcamera/include/.
The directory is added to the compiler headers search path with a meson
include_directories() directive, and internal headers are included with
(e.g. for the internal semaphore.h header)

  #include "semaphore.h"

All was well, until libcxx decided to implement the C++20
synchronization library. The __threading_support header gained a

  #include <semaphore.h>

to include the pthread's semaphore support. As include_directories()
adds src/libcamera/include/ to the compiler search path with -I, the
internal semaphore.h is included instead of the pthread version.
Needless to say, the compiler isn't happy.

Three options have been considered to fix this issue:

- Use -iquote instead of -I. The -iquote option instructs gcc to only
  consider the header search path for headers included with the ""
  version. Meson unfortunately doesn't support this option.

- Rename the internal semaphore.h header. This was deemed to be the
  beginning of a long whack-a-mole game, where namespace clashes with
  system libraries would appear over time (possibly dependent on
  particular system configurations) and would need to be constantly
  fixed.

- Move the internal headers to another directory to create a unique
  namespace through path components. This causes lots of churn in all
  the existing source files through the all project.

The first option would be best, but isn't available to us due to missing
support in meson. Even if -iquote support was added, we would need to
fix the problem before a new version of meson containing the required
support would be released.

The third option is thus the only practical solution available. Bite the
bullet, and do it, moving headers to include/libcamera/internal/.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Jacopo Mondi <jacopo@jmondi.org>
2020-05-16 03:38:11 +03:00
Laurent Pinchart
8daf20485b libcamera: controls: Add zero-copy set API for ControlValue
Extend the ControlValue class with a reserve() function to set the value
without actually copying data, and a non-const data() function that
allows writing data directly to the ControlValue storage. This allows
allocating memory directly in ControlValue, potentially removing a data
copy.

Note that this change was implemented before ByteStreamBuffer gained the
zero-copy read() variant, and doesn't actually save a copy in the
control serializer. It however still simplifies
ControlSerializer::loadControlValue().

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2020-03-23 16:45:16 +02:00
Laurent Pinchart
4e3f835126 libcamera: controls: Add support for string controls
String controls are stored internally as an array of char, but the
ControlValue constructor, get() and set() functions operate on an
std::string for convenience. Array of strings are thus not supported.

Unlike for other control types, the ControlInfo range reports the
minimum and maximum allowed lengths of the string (the minimum will
usually be 0), not the minimum and maximum value of each element.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2020-03-20 16:47:45 +02:00
Laurent Pinchart
e5a9e6e9cd libcamera: controls: Rename ControlRange to ControlInfo
To prepare for storage of additional information in the ControlRange
structure, rename it to ControlInfo.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2020-03-20 16:47:45 +02:00
Laurent Pinchart
73b7ba9da5 libcamera: controls: Name all ControlInfoMap instance variables infoMap
To prepare for the rename of ControlRange to ControlInfo, rename all the
ControlInfoMap instance variables currently named info to infoMap. This
will help avoiding namespace clashes.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2020-03-20 16:47:45 +02:00
Jacopo Mondi
fa252b710a libcamera: control_serializer: Add support for array controls
Add support for serializing and deserializing control values that store
arrays of values. The serialized format is extended to explicitly handle
arrays.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-03-06 18:10:50 +02:00
Laurent Pinchart
7c6f59217e libcamera: control_serializer: Use zero-copy ByteStreamBuffer::read()
Use the zero-copy variant of ByteStreamBuffer::read() to read packet
headers and control entries. This enhances the performance of
ControlList and ControlInfoMap deserialization.

Deserialization of the actual ControlValue is untouched for now and will
be optimized later.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.binghm@ideasonboard.com>
2020-03-06 18:10:49 +02:00
Laurent Pinchart
5467d61925 libcamera: control_serializer: Simplify serialization of ControlValue
Use the ControlValue::data() function to access raw data stored in the
control value and simplify serialization.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.binghm@ideasonboard.com>
2020-03-06 18:10:48 +02:00
Laurent Pinchart
44ff5a18e4 libcamera: control_serializer: Use explicit ControlTypeNone case
Replace the default case with an explicit ControlTypeNone case in
ControlSerializer::load() to catch omissions when adding new control
types.

A return statement needs to be added to the end of the function to avoid
gcc incorrectly reporting that some exit paths don't contain a return
statement. The compiler will still warn that not all cases are handled
when adding a new control type.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-03-06 18:10:45 +02:00
Jacopo Mondi
97cba0ebea libcamera: controls: Add support for byte controls
Add support for byte values to the control framework and to the control
serializer.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-03-06 18:10:37 +02:00
Jacopo Mondi
8b12a161e0 libcamera: controls: Add support for float controls
Add support for float values in Control<> and ControlValue classes.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-03-06 18:10:32 +02:00
Laurent Pinchart
cd0f7929ec libcamera: controls: Expose raw data in ControlValue
Add a data() function to the ControlValue class to expose the raw data
stored by the class as a Span<const uint8_t>. This will be useful to
simplify the serialization of ControlValue instances.

The size computation for the raw data is moved from the
ControlSerializer, which is updated accordingly to use the data()
function in order to access the size. Simplification of the
ControlSerializer will happen in a subsequent change.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-03-06 18:10:24 +02:00
Laurent Pinchart
acf18e4265 libcamera: Switch from utils::make_unique to std::make_unique
Now that we're using C++-14, drop utils::make_unique for
std::make_unique.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-01-14 19:06:40 +02:00
Laurent Pinchart
618b5512a8 libcamera: control_serializer: Initialize serial_
The ControlSerializer::serial_ member variable isn't initialized. Add a
constructor to the class to initialize it.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-01-07 14:14:13 +02:00
Laurent Pinchart
2c5f0ad23a libcamera: Add controls serializer
Add a new ControlSerializer helper to serialize and deserialize
ControlInfoMap and ControlList instances. This will be used to implement
the C IPA protocol and the communication with IPA through IPC.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-11-20 21:47:50 +02:00