The OptionValue toKeyValues() and toArray() functions return a copy of
the values. This is unnecessary, and can cause use-after-free issues
when taking references to the return values. Return references instead
to optimize the implementation and avoid issues.
The behaviour of the two functions is now undefined in case of an option
type mismatch. The current implementation catches this with an
assertion.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
The roles() and updateConfiguration() functions check if the OptStream
OptionValue they receive is empty by first casting it to an array. To
prepare for the toArray() function not allowing such a cast when the
option value is empty, test if the option value is empty instead.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Add a convenience helper to check if an option value is empty, based on
the value type. This is useful as a shortcut syntax to check if an
option has been set.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
While OptionValue cast operators to int and std::string allow useful
shortcut syntaxes, the cast operators to KeyValueParser::Options and
std::vector<OptionValue> are less useful. A an explicit static_cast call
would be more cumbersome to write than an explicit .toKeyValues() or
toArray(), and implicit cast hide too much of what's going on.
Drop those two cast operators, and replace the only implicit cast
occurrence with .toKeyValues(). While at it, drop the local opts
variable in StreamKeyValueParser::roles() as it isn't used.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Add support for creating a tree-based hieararchy of options instead of a
flat list. This is useful to support options that need to be interpreted
in the context of a particular occurrence of an array option.
The usage text automatically documents the options in their
corresponding context:
Options:
-c, --camera camera ... Specify which camera to operate on, by id or by index
-h, --help Display this help message
-I, --info Display information about stream(s)
-l, --list List all cameras
--list-controls List cameras controls
-p, --list-properties List cameras properties
-m, --monitor Monitor for hotplug and unplug camera events
Options valid in the context of --camera:
-C, --capture[=count] Capture until interrupted by user or until <count> frames captured
-F, --file[=filename] Write captured frames to disk
If the file name ends with a '/', it sets the directory in which
to write files, using the default file name. Otherwise it sets the
full file path and name. The first '#' character in the file name
is expanded to the camera index, stream name and frame sequence number.
The default file name is 'frame-#.bin'.
-s, --stream key=value[,key=value,...] ... Set configuration of a camera stream
height=integer Height in pixels
pixelformat=string Pixel format name
role=string Role for the stream (viewfinder, video, still, raw)
width=integer Width in pixels
--strict-formats Do not allow requested stream format(s) to be adjusted
--metadata Print the metadata for completed requests
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
When printing usage information for a key-value parser, the
documentation of the keys and values is printed in the second column of
the usage text:
-s, --stream key=value[,key=value,...] ... Set configuration of a camera stream
height=integer Height in pixels
pixelformat=string Pixel format name
role=string Role for the stream (viewfinder, video, still, raw)
width=integer Width in pixels
-h, --help Display this help message
This results in long lines. Improve this by moving the key description
to the first column, and aligning the value description as other option
description text:
-s, --stream key=value[,key=value,...] ... Set configuration of a camera stream
height=integer Height in pixels
pixelformat=string Pixel format name
role=string Role for the stream (viewfinder, video, still, raw)
width=integer Width in pixels
-h, --help Display this help message
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Copying the OptionsParser class would result in the optionsMap_ entries
pointing to Option entries of the original instance. As there's no use
case for copying the class, disable copying.
Disable copying of KeyValueParser as well for consistency as there's no
use case either.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Add an Option::optionName() function that returns a string describing
the option name, with leading dashes. As a result,
OptionsParser::parseValueError() function becomes a single-line function
and can be inlined in its caller.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
To prepare for usage of the OptionsParser::Options class in OptionValue,
move the definition of the OptionValue class after OptionsParser. There
is no functional change.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
The Option structure is an internal implementation detail and shouldn't
be exposed in the API. Move it to options.cpp. This requires moving the
inline constructors and destructors for the KeyValueParser and
OptionsParser classes to options.cpp as well, as they need a full
definition of the Option structure.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
The KeyValueParser::usage() function is meant to be called from an
OptionsParser or another KeyValueParser only. Make it private, and set
the OptionsParser class as a friend of the KeyValueParser class.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Building the cam application isn't always desired, for instance in a
production environment that only needs the libcamera library. Add a
meson option to disable it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
In preparation to register the Location property only if the firware
interface provides it, do not assume it is available and build the
camera name using the camera sensor model as a fallback.
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
The cam option --capture=N is suppose to only capture N requests. But if
the processing done for each request is large (such as writing it to a
slow disk) the current implementation could queue more than N requests
before the exit condition is detected and capturing stopped.
Solve this by only queueing N requests while still waiting for N
requests to complete before exiting.
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cam uses libevent to deal with threads and idle loop while still
implementing its own event queue. This creates issues when the event
loop is terminated as it might get stuck in the idle loop if exit() is
called while the thread is busy with dispatchCalls().
Solve this by removing the custom event execution and instead injecting
the calls as events to the base event loop.
Reported-by: Sebastian Fricke <sebastian.fricke@posteo.net>
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
The 'event' variable name is usually used for events added to the base
event loop, not the loop itself. Rename the struct event_base member to
base_ as a preparation for future work adding events to the loop.
There is no functional change.
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
The request completion handler is invoked in the camera manager thread,
which shouldn't be blocked for large amounts of time. As writing the
frames to disk can be a time-consuming process, move request processing
to the main thread by queueing an event to the event loop.
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>
The parseValue function is given the optarg directly from the getopt
library, but the function retains the same name.
This causes an shadowed variable of the global optarg variable to be
present in the parseValue function. While this is not harmful, rename it
to work towards disabling shadowed variables.
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
operator[] doesn't check if the option exists in the values_ map, so it
can return a pointer to location outside the map.
Fix by returning an empty OptionValue if the option is not found.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@iki.fi>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
[Kieran: Adjust s_empty naming to 'empty']
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Allow reuse of the Request object by implementing reuse(). This means
the applications now have the responsibility of freeing the Request
objects, so make all libcamera users (cam, qcam, v4l2-compat, gstreamer,
android) do so.
Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Instead of only printing the camera ID which is not intended for humans
to read and parse create a more user-friendly string when printing
camera names. The ID is still printed as it is one option used to select
camera using the --camera option.
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <email@uajain.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
The payload size in a captured framebuffer is usually equal to the
buffer size. However, for compressed formats, the payload may be
smaller Only write the payload when capturing to a file.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Print the timestamp of the captured buffer in addition to the frame
rate, as this is more precise information that can help debugging issue.
The log changes from
Using camera \_SB_.PCI0.XHC_.RHUB.HS05-5:1.0-0bda:58f4
Capture until user interrupts by SIGINT
fps: 0.00 stream0 seq: 000000 bytesused: 169968
fps: 28.57 stream0 seq: 000002 bytesused: 170352
fps: 31.25 stream0 seq: 000003 bytesused: 170428
fps: 32.26 stream0 seq: 000004 bytesused: 170672
fps: 27.78 stream0 seq: 000005 bytesused: 170568
to
Using camera \_SB_.PCI0.XHC_.RHUB.HS05-5:1.0-0bda:58f4
Capture until user interrupts by SIGINT
93473.942525 (0.00 fps) stream0 seq: 000000 bytesused: 183940
93474.006528 (15.62 fps) stream0 seq: 000002 bytesused: 183512
93474.038525 (31.25 fps) stream0 seq: 000003 bytesused: 183760
93474.074530 (27.77 fps) stream0 seq: 000004 bytesused: 182704
93474.106581 (31.20 fps) stream0 seq: 000005 bytesused: 182768
While at it, compute the frame rate on the buffer timestamps instead of
sampling the clock in the request completion handler.
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>
We build libcamera with -Wno-unused-parameter and this doesn't cause
much issue internally. However, it prevents catching unused parameters
in inline functions defined in public headers. This can lead to
compilation warnings for applications compiled without
-Wno-unused-parameter.
To catch those issues, remove -Wno-unused-parameter and fix all the
related warnings with [[maybe_unused]].
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>
The Stream pointer just acts as a key in the Request object. There is no
good use-case to modify a stream from a pointer retrieved from the
Request, make it const. This allows pipeline handlers to better express
that the Stream pointer is retrieved in a Request should just be treated
as a key.
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Declare a using directive for the map of Stream to FrameBuffer. Update
all users of Request::buffers() to use the new usage directive.
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Rename Camera::name() to camera::id() to better describe what it
represents, a unique and stable ID for the camera. While at it improve
the documentation for the camera ID to describe it needs to be stable
for a camera between resets of the system.
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
The different error paths in init() are out of sync. Instead of fixing
them switch to using the cleanup() function which does the right thing
for all cases.
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Extend the '--capture' option with and optional numerical argument to be
able to specify how many frames to capture before exiting. If the
optional argument is not provided the old behavior of running until the
user interrupts with a SIGINT is retained.
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Several headers belonging to cam and qcam use __LIBCAMERA_*_H__ as a
header guard. They're not part of the libcamera core, use __CAM_*_H__
and __QCAM_*_H__ instead, similarly to all other headers of cam and
qcam.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
In an attempt to clarify the license terms of all files in the libcamera
project, the build system files deserve particular attention. While they
describe how the binaries are created, they are not themselves
transformed into any part of binary distributions of the software, and
thus don't influence the copyright on the binary packages. They are
however subject to copyright, and thus influence the distribution terms
of the source packages.
Most of the meson.build files would not meet the threshold of
originality criteria required for copyright protection. Some of the more
complex meson.build files may be eligible for copyright protection. To
avoid any ambiguity and uncertainty, state our intent to not assert
copyrights on the build system files by putting them in the public
domain with the CC0-1.0 license.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Giulio Benetti <giulio.benetti@micronovasrl.com>
Acked-by: Jacopo Mondi <jacopo@jmondi.org>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Acked-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Acked-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Acked-by: Paul Elder <paul.elder@ideasonboard.com>
Acked-by: Show Liu <show.liu@linaro.org>