Commit Graph

29 Commits

Author SHA1 Message Date
Barnabás Pőcze
f84522d7cd libcamera: controls: Expose string controls as std::string_view
When retrieving the value from a `ControlValue` usually one of two
things happen: a small, trivially copyable object is returned by
value; or a view into the internal buffer is provided. This is true
for everything except strings, which are returned in `std::string`,
incurring the overhead of string construction.

To guarantee no potentially "expensive" copies, use `std::string_view`
pointing to the internal buffer to return the value. This is similar
to how other array-like types are returned with a `Span<>`.

This is an API break, but its scope is limited to just `properties::Model`.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=256
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-10-08 13:02:19 +02:00
Milan Zamazal
baea40a8a5 apps: cam: Support PPM output for other RGB formats
GPU ISP can produce only 32-bit output.  Let's add support to the PPM
writer for all the common RGB image formats so that we can store GPU ISP
output as PPM files.  Contingent alpha values are ignored as there is no
support for the alpha channel in PPM.

There is no obvious performance penalty in my environment compared to
output in the raw format.

Signed-off-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-09-04 12:13:00 +01:00
Barnabás Pőcze
af43c2f945 apps: common: options: Avoid copying in range based for loop
The copy can trigger `-Wrange-loop-construct` and is not needed,
so use a reference to avoid it.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-08-15 11:22:28 +02:00
Barnabás Pőcze
b544ce1c19 apps: common: image: Fix assertion
`plane` must be strictly less than the vector's size,
it cannot be equal to it.

Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-06-16 10:57:54 +02:00
Paul Elder
ee2b011b65 apps: cam: Try raw role if default viewfinder role fails
cam currently defaults to the viewfinder role when no role is specified.
This means that on platforms that only support the raw role (such as a
raw sensor with no softISP on a simple pipeline platform),
generateConfiguration() would return nullptr and cam would bail out.

At least this is what is supposed to happen based on the little
documentation that we have written regarding generateConfiguration(),
specifically in the application writer's guide, which is probably the
most influential piece of documentation:

  The ``Camera::generateConfiguration()`` function accepts a list of
  desired roles and generates a ``CameraConfiguration`` with the best
  stream parameters configuration for each of the requested roles. If the
  camera can handle the requested roles, it returns an initialized
  ``CameraConfiguration`` and a null pointer if it can't.

Currently the simple pipeline handler will return a raw configuration
anyway (if it only supports raw) even if a non-raw role was requested.
Thus cam receives a raw configuration instead of a nullptr when no role
is specified and viewfinder is requested.

However, in the near future, support for raw streams with softISP on the
simple pipeline handler will be merged. This will notably change the
behavior of the simple pipeline handler to return nullptr if a non-raw
role was requested on a platform that only supports raw. This is proper
behavior according to documentation, but changes cam's behavior as it
used to capture fine with no parameters but will no longer be able to.

Technically this is an issue with the roles API, as we are mixing
roles in the sense of "configuration hints" (eg. viewfinder vs recording
vs still capture) with roles in the sense of "platform capabilities"
(raw vs everything else). In the long term the proper solution is to
rework the roles API.

In the meantime, fix cam so that it will try the raw role if the default
viewfinder role returns no configuration. cam is an app that is capable
of using the raw stream, so this is appropriate behavior. If roles are
specified, then do not retry, as in this situation the user knows what
streams they can use and what they want.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2025-04-29 00:57:54 +09:00
Barnabás Pőcze
3939c316f0 apps: common: event_loop: Remove unused type alias
The type alias `duration` is not used anywhere, so remove it.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 17:29:28 +01:00
Barnabás Pőcze
234eb60546 apps: common: event_loop: Use single event source for deferred calls
Instead of calling `event_base_once()` every time a deferred call
is added to the loop, create an event source at construction, and
simply trigger that when a new deferred call is scheduled.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 17:29:28 +01:00
Barnabás Pőcze
54055dd0c2 apps: common: event_loop: Use std::deque instead of std::list
Deque has fast pop_front and push_back operations while making
fewer allocations for the same number of elements as an `std::list`.
So use an `std::deque` for storing the deferred calls of the loop.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-27 17:29:28 +01:00
Barnabás Pőcze
a0f4092c6c apps: common: event_loop: Disable copy/move
The compiler generated functions are not appropriate, so
delete the copy/move constructor/assignment to avoid
potential issues.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-02-27 17:29:28 +01:00
Barnabás Pőcze
b1b99f4d66 apps: common: event_loop: Take callbacks by rvalue ref
Using a const lvalue reference to `std::function<>` is not ideal
because it forces a copy to happen. Use an rvalue reference and
`std::move()` to avoid that.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-02-27 17:29:28 +01:00
Milan Zamazal
33ce463a46 libcamera: formatting: Avoid spaces in for loops without expression
The clang formatter removes spaces in places of empty expressions in for
loops.  For example, it changes

  for (init; condition; )

to

  for (init; condition;)

libcamera currently uses both the styles and we should use only one of
them for consistency.  Since there is apparently no option to override
the formatter behavior (see
https://clang.llvm.org/docs/ClangFormatStyleOptions.html), let's remove
the extra spaces to make the formatter happy.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-02-26 02:27:18 +02:00
Milan Zamazal
8aef7b4dfb apps: ppm_writer: Return EIO on I/O errors
EINVAL should be returned only when the requested format is unsupported.
On errors when writing the data, let's return EIO, which is the closest
description of the situation when we don't inspect it more.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-27 00:06:11 +02:00
Milan Zamazal
8072518ca9 apps: ppm_writer: Add a missing include
<errno.h> should be included in the ppm writer, as the source of the
error code constants used there.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-01-27 00:05:56 +02:00
Laurent Pinchart
2e47324860 apps: Replace HAVE_DNG with HAVE_TIFF
Support for DNG capture is conditioned by the availability of libtiff,
which is indicated by the HAVE_TIFF macro set by meson. The dng_writer.h
header then defines HAVE_DNG, which is used in a couple of places to
conditionally compile DNG-related code. Most of the other locations
where conditional compilation is required use HAVE_TIFF.

Using both HAVE_TIFF and HAVE_DNG is confusing. HAVE_DNG would be a
better name, but as the macro is defined in dng_writer.h, it would
require all files that need to test for DNG support to include that
header. Failure to include it (directly or indirectly) would result in
the code covered by the macro to be silently disabled.

To avoid the confusion, standardize on using HAVE_TIFF everywhere and
drop HAVE_DNG.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-09-30 10:56:48 +03:00
Laurent Pinchart
7f33dfc100 libcamera: Avoid variable-length arrays
Unlike in C where they have been standardized since C99, variable-length
arrays in C++ are an extension supported by gcc and clang. Clang started
warning about this with -Wall in version 18:

src/libcamera/ipc_unixsocket.cpp:250:11: error: variable length arrays in C++ are a Clang extension [-Werror,-Wvla-cxx-extension]
  250 |         char buf[CMSG_SPACE(num * sizeof(uint32_t))];
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

One simple option is to disable the warning. However, usage of VLAs in
C++ is discouraged by some, usually due to security reasons, based on
the rationale that developers are often unaware of unintentional use of
VLAs and how they may affect the security of the code when the array
size is not properly validated.

This rationale may sound dubious, as the most commonly proposed fix is
to replace VLAs with vectors (or just arrays dynamically allocated with
new() wrapped in unique pointers), without adding any size validation.
This will not produce much better results. However, keeping the VLA
warning and converting the code to dynamic allocation may still be
slightly better, as it can prompt developers to notice VLAs and check if
size validation is required.

For these reasons, convert all VLAs to std::vector. Most of the VLAs
don't need extra size validation, as the size is bound through different
constraints (e.g. image width for line buffers). An arguable exception
may be the buffers in IPCUnixSocket::sendData() and
IPCUnixSocket::recvData() as the number of fds is not bound-checked
locally, but we will run out of file descriptors before we could
overflow the buffer size calculation.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Acked-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2024-07-31 01:22:13 +03:00
Laurent Pinchart
e3310749f5 apps: common: dng_writer: Fix RAW10 and RAW12 packing on BE machines
The 16-bit padded raw 10 and raw 12 formats are stored in memory in
little endian order, regardless of the machine's endianness. Read pixel
data as uint8_t values and hardcode bit shifting to little endian to fix
scanline packing.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-07-01 10:53:06 +03:00
Laurent Pinchart
7735d65ce8 apps: common: dng_writer: Fix thumbnail generation on BE machines
The 16-bit padded raw 10 and raw 12 formats are stored in memory in
little endian order, regardless of the machine's endianness. Swap the
16-bit values on big-endian machines when reading pixels from memory to
generate thumbnails.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2024-07-01 10:28:48 +03:00
Stefan Klug
e9dc398b92 apps: common: dng_writer: Support RAW10 and RAW12 format
Add support for RAW10 and RAW12 to the dng_writer. This is needed on
imx8mp to produce tuning images.  Both formats were tested on a debix
som with a imx335.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-29 00:18:34 +03:00
Stefan Klug
4513db58c0 apps: common: dng_writer: Add thumbnail scanline function for Raw
Add a thumbnail function for raw formats that are 16bit aligned.
This is needed for the upcoming RAW10 and RAW12 implemntation.

Use the new function for RAW16 as the thumbScanlineRaw_CSI2P produces
incorrect results for that format (it averages over adjacent bytes,
which works for the CSI formats).

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-29 00:18:30 +03:00
Stefan Klug
a47ab2711d apps: common: dng_writer: Rename packing functions
The old names lead to confusions. Rename to better express the intent.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-29 00:16:51 +03:00
Daniel Scally
5155150bbf apps: common: dng_writer: Support RAW16 formats
Add support for RAW16 formats to the DNGWriter helpers so that we can
produce dng files from the mali-c55.

Signed-off-by: Daniel Scally <dan.scally@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-29 00:16:42 +03:00
Stefan Klug
36a4f67a75 apps: common: dng_writer: Workaround for "Unknown tag 33421" error
In libtiff version 4.5.1 and later the CFA* tags were missing. This got
fixed in 49856998c3
Unfortunately the fix is not released yet, but the faulty libtiff is
contained in current buildroot. As a local fix is pretty easy and
without side effects, let's workaround that.

Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-06-26 15:48:34 +02:00
Laurent Pinchart
37d81a390b apps: Define local functions in anonymous namespace
Multiple local functions are defined in the global namespace without the
static keyword. This compiles fine for now, but will cause a missing
declaration warning when we enable them. To prepare for that, move the
function declaration to an anonymous namespace.

While at it, for consistency, include an existing static function in the
namespace and drop the static keyword.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2024-06-26 12:07:11 +03:00
Laurent Pinchart
626172a16b libcamera: Drop file name from header comment blocks
Source files in libcamera start by a comment block header, which
includes the file name and a one-line description of the file contents.
While the latter is useful to get a quick overview of the file contents
at a glance, the former is mostly a source of inconvenience. The name in
the comments can easily get out of sync with the file name when files
are renamed, and copy & paste during development have often lead to
incorrect names being used to start with.

Readers of the source code are expected to know which file they're
looking it. Drop the file name from the header comment block.

The change was generated with the following script:

----------------------------------------

dirs="include/libcamera src test utils"

declare -rA patterns=(
	['c']=' \* '
	['cpp']=' \* '
	['h']=' \* '
	['py']='# '
	['sh']='# '
)

for ext in ${!patterns[@]} ; do
	files=$(for dir in $dirs ; do find $dir -name "*.${ext}" ; done)
	pattern=${patterns[${ext}]}

	for file in $files ; do
		name=$(basename ${file})
		sed -i "s/^\(${pattern}\)${name} - /\1/" "$file"
	done
done
----------------------------------------

This misses several files that are out of sync with the comment block
header. Those will be addressed separately and manually.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
2024-05-08 22:39:50 +03:00
Milan Zamazal
666f17affc apps: cam: Add support for PPM output format
When file output is requested from cam app, it simply dumps the
processed data and it must be converted to a readable image format
manually. Let's add support for PPM output file format to make files
produced by cam directly readable by image display and processing
software.

For now, only BGR888 output format, which is the simplest one to use, is
supported but nothing prevents adding support for other output formats
if needed. Nevertheless, they would typically need byte reordering or
other conversions for PPM file format. It may be better to find a way to
dump the image data in other output formats directly using some of the
already existing file formats or raw file format converters.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-03-28 03:11:59 +02:00
Paul Elder
64502c8d4a apps: common: dng_writer: Add a default case for switch-case on a modulo
Clearly all cases in the switch are already satisfied, but some
compilers fail to realize this and spit out an error:

Compiler version: gcc 11.2.0 "aarch64-buildroot-linux-gnu-gcc.br_real (Buildroot 2021.11) 11.2.0"

../../src/apps/common/dng_writer.cpp: In function ‘void thumbScanlineIPU3(const FormatInfo&, void*, const void*, unsigned int, unsigned int)’:
../../src/apps/common/dng_writer.cpp:277:55: error: ‘val4’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  277 |                 uint8_t value = (val1 + val2 + val3 + val4) >> 10;
      |                                                       ^~~~
../../src/apps/common/dng_writer.cpp:277:48: error: ‘val3’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  277 |                 uint8_t value = (val1 + val2 + val3 + val4) >> 10;
      |                                                ^~~~
../../src/apps/common/dng_writer.cpp:277:41: error: ‘val2’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  277 |                 uint8_t value = (val1 + val2 + val3 + val4) >> 10;
      |                                         ^~~~
../../src/apps/common/dng_writer.cpp:277:34: error: ‘val1’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  277 |                 uint8_t value = (val1 + val2 + val3 + val4) >> 10;
      |                                  ^~~~

Add a default case for the switch-case on a modulo to silence this.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=207
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2024-01-24 17:29:24 +02:00
Barnabás Pőcze
26a4b83d1b libcamera: Remove StreamRoles alias
Now that `Camera::generateConfiguration()` takes a `libcamera::Span`
of `StreamRole`, remove the `StreamRoles` type, which was an alias
to `std::vector<libcamera::StreamRole>`.

The removal has two reasons:
 - it is no longer strictly necessary,
 - its presence may suggest that that is the preferred (or correct)
   way to build/pass a list of `StreamRole`.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
[Kieran: Fix small checkstyle report on roles initialiser]
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2023-07-04 22:56:38 +01:00
Barnabás Pőcze
58e0b6e18c apps: Return std::optional<> from StreamKeyValueParser::parseRole()
Instead of having bool return type and an out parameter, use
std::optional<libcamera::StreamRole> to return from
StreamKeyValueParser::parseRole().

Meanwhile at it, re-word an existing comment to make it lucid.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
2023-02-15 01:32:05 +05:30
Laurent Pinchart
a8113fb3a8 apps: Share common source between applications
Multiple source files in the src/apps/cam/ directory are used by cam,
qcam and lc-compliance. They are compiled separately for each
application. Move them to a new src/apps/common/ directory and compile
them in a static library to decrease the number of compilation
operations.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2022-10-24 23:11:37 +03:00