Commit graph

43 commits

Author SHA1 Message Date
Niklas Söderlund
f28ca20960 libcamera: Use PixelFormat instead of unsigned int where appropriate
Use the PixelFormat instead of unsigned int where a pixel format is to
be used. PixelFormat is defined as an unsigned int but is about to be
turned into a class to add functionality.

There is no functional change in this patch.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-03-18 18:02:40 +01:00
Jacopo Mondi
a14b6baca9 cam: Add option to list camera properties
Add the '-p'|'--list-properties' option to the cam application to list
the properties of a camera.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-03-06 18:35:36 +02:00
Niklas Söderlund
1d32f21136 cam: Store camera as shared pointer everywhere
Do not store the camera raw pointer in the capture class, this will
prevent forwarding the shared pointer in the future.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-11-20 17:19:58 +01:00
Laurent Pinchart
53704ac3f4 libcamera: camera_manager: Construct CameraManager instances manually
The CameraManager class is not supposed to be instantiated multiple
times, which led to a singleton implementation. This requires a global
instance of the CameraManager, which is destroyed when the global
destructors are executed.

Relying on global instances causes issues with cleanup, as the order in
which the global destructors are run can't be controlled. In particular,
the Android camera HAL implementation ends up destroying the
CameraHalManager after the CameraManager, which leads to use-after-free
problems.

To solve this, remove the CameraManager::instance() method and make the
CameraManager class instantiable directly. Multiple instances are still
not allowed, and this is enforced by storing the instance pointer
internally to be checked when an instance is created.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-08-19 19:07:45 +03:00
Niklas Söderlund
802d47068b cam: Add --info option to print information about stream(s)
Add a new option to the cam tool that prints information about the
configuration supplied by the user. If the option is specified,
information about the configuration is printed after the configuration
has been verified and possibly adjusted by the camera.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-06-19 12:25:12 +02:00
Niklas Söderlund
7c856201c7 cam: Validate camera configuration
Use CameraConfiguration::validate() to validate and possibly update the
camera configuration when its prepared.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-06-19 12:25:12 +02:00
Niklas Söderlund
afef18d35a cam: Move camera configuration preparation to CamApp
Most of the camera configuration preparation that is done in the
Capture module is not specific to capturing and could be useful for
other modules. Extract the generic parts to CamApp and do basic
preparation of the configuration before passing it to modules.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-06-19 12:25:12 +02:00
Laurent Pinchart
c6090542cd cam: Allow selecting cameras by index
As camera names can be cumbersome to type, selection of cameras by index
from a list can be useful. Print the list of detected cameras with an
index for each item, and interpret the camera name as an index if it is
a numerical value in the range from 1 to the number of cameras.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-06-18 23:34:03 +03:00
Niklas Söderlund
238919be59 cam: Fix cam --help crash
The cam utility does not terminate correctly if invoked with only
--help. It prints the help information and then segfaults due to the
application incorrectly handling the return value. Fix this by moving
the return code check of the option parsing to main().

Reported-by: Emmanuel Arias <eamanu@eamanu.com>
Suggested-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-06-10 23:05:04 +02:00
Niklas Söderlund
633a56d7cd cam: Add CamApp class
Add more structure to main.cpp by breaking up the logic into a CamApp
class. This makes the code easier to read and removes all of the
organically grown global variables.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-25 14:27:55 +02:00
Niklas Söderlund
e741a5482c cam: capture: Break out capture to a new class
Reduce the complexity of main.cpp by compartmentalising the capture
logic into its own class. There is no functional change.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-25 14:27:55 +02:00
Laurent Pinchart
8d846ed8a7 cam: Rename conf variable referring to command line option to opt
Naming a variable that refers to command line options 'conf' is
confusing as we using 'config' and 'cfg' to refer to camera and stream
configurations. Rename it to 'opt'.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-05-23 11:39:46 +03:00
Laurent Pinchart
2b1a908b52 libcamera: camera: Add a validation API to the CameraConfiguration class
The CameraConfiguration class implements a simple storage of
StreamConfiguration with internal validation limited to verifying that
the stream configurations are not empty. Extend this mechanism by
implementing a smart validate() method backed by pipeline handlers.

This new mechanism changes the semantic of the camera configuration. The
Camera::generateConfiguration() operation still generates a default
configuration based on roles, but now also supports generating empty
configurations to be filled by applications. Applications can inspect
the configuration, optionally modify it, and validate it. The validation
implements "try" semantics and adjusts invalid configurations instead of
rejecting them completely. Applications then decide whether to accept
the modified configuration, or try again with a different set of
parameters. Once the configuration is valid, it is passed to
Camera::configure(), and pipeline handlers are guaranteed that the
configuration they receive is valid.

A reference to the Camera may need to be stored in the
CameraConfiguration derived classes in order to access it from their
validate() implementation. This must be stored as a std::shared_ptr<> as
the CameraConfiguration instances belong to applications. In order to
make this possible, make the Camera class inherit from
std::shared_from_this<>.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-05-23 01:07:38 +03:00
Laurent Pinchart
75de3bff9e libcamera: camera: Return a pointer from generateConfiguration()
To prepare for specialising the CameraConfiguration class in pipeline
handlers, return a pointer to a camera configuration instead of a
reference from Camera::generateConfiguration(). The camera configuration
always needs to be allocated from the pipeline handler, and its
ownership is passed to the application.

For symmetry, change Camera::configure() to take a CameraConfiguration
pointer instead of a reference. This aligns with our coding practice of
passing parameters that are modified by the callee by pointer.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-05-23 01:07:21 +03:00
Laurent Pinchart
77ae64eb24 libcamera: Refactor the camera configuration storage and API
Refactor the CameraConfiguration structure to not rely on Stream
instances. This is a step towards making the camera configuration object
more powerful with configuration validation using "try" semantics.

The CameraConfiguration now exposes a simple vector-like API to access
the contained stream configurations. Both operator[]() and at() are
provided to access elements. The isEmpty() method is renamed to empty()
and the methods reordered to match the std::vector class.

As applications need access to the Stream instances associated with the
configuration entries in order to associate buffers with streams when
creating requests, expose the stream selected by the pipeline handler
through a new StreamConfiguration::stream().

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-05-23 00:27:14 +03:00
Laurent Pinchart
a40023e6cc libcamera: Use stream roles directly instead of StreamUsage
In order to prepare for an API overhall of the camera configuration
generation, remove the StreamUsage class and replace its uses by stream
roles. The size hints can't be specified anymore, and will be replaced
with an API on the StreamConfiguration to negotiate configuration
parameters with cameras.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-05-23 00:27:13 +03:00
Laurent Pinchart
2ca2d65870 libcamera: camera: Rename configureStreams() and streamConfiguration()
Rename the configureStreams() and streamConfiguration() methods to
configure() and generateConfiguration() respectively in order to clarify
the API. Both methods deal with CameraConfiguration objects, and are
thus not limited to streams, even if a CameraConfiguration currently
contains streams only.

While at it, remove the qcam MainWindow::configureStreams() method that
is declared but never defined or used.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-05-23 00:27:10 +03:00
Laurent Pinchart
a2dddf7c26 libcamera: Use the Size class through libcamera
Several of our structures include width and height fields that model a
size while we have a Size class for that purpose. Use the Size class
through libcamera, and give it a toString() method like other geometry
and format classes.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-04-30 22:18:42 +03:00
Niklas Söderlund
248dc97024 cam: Allow cameras with more than one stream
The libcamera API and the cam tool are now ready to make use of cameras
with more than one stream. Remove the limitation in the tool which
disallows cameras that provide more than one stream.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-04-09 17:01:00 +02:00
Niklas Söderlund
c1df18cab6 cam: Extend request completion handler to deal with multiple streams
The completion handler needs to handle all buffers in the request. Solve
this by iterating over all buffers in the completed request. The streams
are named automatically streamX, where X is the order in which the
stream was passed to configureStream().

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-04-09 17:00:27 +02:00
Niklas Söderlund
e65e5d59f4 cam: Add support to specify multiple stream configurations with roles
Extend the cam tool to allow configuring more than one stream. Add an
optional parameter to the --stream option to specify a usage role for
the stream. The stream role is passed to libcamera to give it control
over which streams to use.

To support multiple streams, creation of requests needs to be reworked
to limit the number of requests to match the stream with the least
number of buffers. This should be improved in the future as the tool and
the library evolve.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-04-09 16:59:19 +02:00
Niklas Söderlund
47a9f357fe cam: Extend BufferWriter to include a stream name in file path
To be able to write multiple buffers captured in the same request (and
hence having the same sequence number) the buffer writer needs to name
each file uniquely. Add a stream name to the writer function which the
buffer writer can add to the part of the pattern it already expands to
the sequence number. As cam only supports one stream, hard code the name
to stream0.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-04-09 16:59:19 +02:00
Niklas Söderlund
ea34d1a574 cam: Rename --format to --stream
More than format information needs to be supplied for each stream to
allow multiple streams to be configured. Rename the option and adapt all
usages of it. There is no functional change except the rename.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-04-09 16:59:19 +02:00
Niklas Söderlund
b0c730e330 libcamera: Switch to CameraConfiguration
Implement the camera configuration thru out the library, tests, cam and
qcam tools.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-04-09 16:59:19 +02:00
Niklas Söderlund
20a6455e0b libcamera: camera: Add support for stream usages
Instead of requesting the default configuration for a set of streams
where the application has to figure out which streams provided by the
camera is best suited for its intended usage, have the library figure
this out by using stream usages.

The application asks the library for a list of streams and a suggested
default configuration for them by supplying a list of stream usages.
Once the list is retrieved the application can fine-tune the returned
configuration and then try to apply it to the camera.

Currently no pipeline handler is prepared to handle stream usages but
nor did it make use of the list of Stream IDs which was the previous
interface. The main reason for this is that all cameras currently only
provide one stream each. This will still be the case but the API will be
prepared to expand both pipeline handlers and applications to support
streams usages.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-04-05 22:07:47 +02:00
Niklas Söderlund
30fe5bde5f cam: Rework how streams configuration is prepared
In preparation of reworking how a default configuration is retrieved
from a camera separate preparation of stream configuration and
application into two different functions. Reason for this is that
preparation of camera configuration will become more complex.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-04-04 00:21:22 +02:00
Laurent Pinchart
f8386836df cam: Separate options valid() and empty()
An empty option list is not necessarily an error. Add a new empty()
function to test the option list for emptiness, and modify the valid()
function to only notify parsing errors. As a side effect this allows
accessing partially parsed options, which may be useful in the future.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-03-27 18:26:15 +02:00
Laurent Pinchart
54e6a3eb1f cam: Don't requeue requests when stopping stream
When stopping the stream all pending requests are cancelled, resulting
in the request completion signal being emitted with the request status
set appropriately. Check the request status in the request completion
slot and skip requeuing the request if it has been cancelled.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-03-01 20:46:43 +02:00
Niklas Söderlund
132ce9c1cf libcamera: store stream pointers in sets instead of a vectors
The arrays that store Stream pointers shall always contain unique
values. Storing them in vectors opens up for the same stream pointer
appearing twice. Remove this possibility by storing them in a set which
guarantees each element is unique.

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>
2019-02-28 18:41:52 +01:00
Niklas Söderlund
dc01a5bc43 cam: fix order camera is operated on
Upcoming enforcing of order the camera shall be operate on is not
compatible with the cam utility. Requests shall be queued after the
camera is started, not before.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-28 18:41:21 +01:00
Niklas Söderlund
374c102073 cam: Improve when usage information is printed
Running the cam tool without any options results in the tool to exit
with EXIT_FAILURE but no usage being printed, this is confusing. Improve
this by also printing the usage text.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-25 23:14:39 +01:00
Niklas Söderlund
71e84c22da cam: fix printing of camera name
Since commit c8c546fe99 ("cam: options: Add option type handling
to options parser") introduced type handling for options the context the
option is read became important. When reading the camera option for
printing there is no explicit context to print it as a string and
instead the int context was chosen resulting in:

    $ cam --camera foo
    Camera 0 not found

While the expected output is:

    $ cam --camera foo
    Camera foo not found

Fix this by providing the correct context for the camera option when
printing it.

Fixes: c8c546fe99 ("cam: options: Add option type handling to options parser")
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-25 23:13:33 +01:00
Niklas Söderlund
dd14f1ec2c cam: improve error checking when capturing
The return value when start() and stop() the camera should be checked
and handled.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-25 23:13:33 +01:00
Niklas Söderlund
24cb563853 cam: free allocated buffers when done capturing
The allocated buffers needs to be freed once the application is done
with them.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-25 23:13:33 +01:00
Niklas Söderlund
2090f8fdd8 cam: fix return type of configureStreams()
The only caller of configureStreams() stores its return value as an int
and not bool. This is confusing and also prevents the (possibly)
different error codes returned by Camera::configureStreams() to be
propagated inside the cam tool. Fix this by changing the return type to
int and propagate the return value from the camera.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-25 23:12:57 +01:00
Niklas Söderlund
8b27416267 cam: Add option to write raw frames to disk
Use the helper BufferWriter to optionally write frames to disk as they
are captured.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-06 08:03:03 +02:00
Niklas Söderlund
dbe7a28377 cam: Add capture operation
Add an option to capture frames from a camera and keep it running until
the user terminates by sending SIGINT.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-06 08:03:03 +02:00
Niklas Söderlund
86a7b45bdb cam: Add --format option to configure a stream
Add an option to configure the first stream of a camera from an argument
with options and parse the width, height and pixel format from that
list.

The pixel format is still specified as a integer which should correspond
to the kernels FOURCC identifiers. Going forward this should be turned
into a string representation and the cam parser should translate between
the two.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-01 11:42:06 +02:00
Laurent Pinchart
c8c546fe99 cam: options: Add option type handling to options parser
Extend the options parser with support for option types. All options
must now specify the type of their argument, and the parser
automatically parses the argument and handles errors internally.
Available types are none, integer or string.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-02-01 11:42:02 +02:00
Niklas Söderlund
0b2822749e cam: options: Move enum OptionArgument
The enumeration of the different possibilities for arguments can be used
by other parser then OptionsParser. Move it outside the class to make it
ready to be used by other parsers.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-02-01 11:41:53 +02:00
Laurent Pinchart
71ef5532d9 cam: Add event loop
Add a simple event loop to the cam application and use it in the main()
function, with an example of how to handle SIGINT to gracefully stop the
loop.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-01-25 17:41:03 +02:00
Laurent Pinchart
a22dcaaa78 cam: options: Don't implement move semantics for OptionsParser::Options
The compiler creates a move constructor automatically when none is
supplied, and it does the right thing by default in this case. Using
std::move() inside the function prevents the compiler from doing
return value optimization and actually hinders performances. Using
std::move() in the caller is unnecessary, the move constructor is used
automatically by the compiler.

For all these reasons remove the tentative optimization that resulted in
worse performances and worse code.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-01-22 20:44:04 +02:00
Laurent Pinchart
f5e48ebf44 cam: Extract option parser to separate file
And turn it into an OptionsParser object.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-01-22 14:04:09 +01:00