Age | Commit message (Collapse) | Author |
|
When creating a DRM frame buffer, the dmabufs for the planes are
imported as GEM objects. For multi-planar formats, all planes may use
the same dmabuf, which results in multiple imports. This doesn't cause
any issue at import time, as DRM detects this situation and returns the
same GEM object. However, when destroying the frame buffer, the same GEM
object ends up being closed multiple times, which generates an error.
Fix this by avoiding multiple imports of the same dmabuf for the same
frame buffer. While the issue may theoretically occur with identical
dmabufs for different frame buffers, this is quite unlikely and is thus
not addressed.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Now that libcamera supports per-plane offsets, pass the values to
drmModeAddFB2(). The KMS sink in cam is now capable of rendering
multi-planar formats.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
The stride is not always identical for all planes for multi-planar
formats. Semi-planar YUV formats without horizontal subsampling often
have a chroma stride equal to twice the luma stride, and tri-planar YUV
formats with a 1/2 horizontal subsampling often have a chroma stride
equal to half the luma stride. This isn't correctly taken into account
when creating a DRM frame buffer, as the same stride is set for all
planes.
libcamera doesn't report per-plane stride values yet, but uses chroma
strides that match the above description for all currently supported
platforms. Calculation the chrome strides appropriately in the KMSSink
class, and pass them to DRM::createFrameBuffer().
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Replace the manual implementation of frame buffer mapping with the Image
class to improve code sharing.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
The new Image class represents a multi-planar image with direct access
to pixel data. It currently duplicates the function of the
MappedFrameBuffer class which is internal to libcamera, and will serve
as a design playground to improve the API until it is considered ready
to be made part of the libcamera public API.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
The number of metadata planes should always match the number of frame
buffer planes. Enforce this by making the vector private and providing
accessor functions.
As this changes the public API, update all in-tree users accordingly.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
|
|
This fixes the way of mapping FrameBuffer in FrameSink by
using offset.
Signed-off-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
|
Use the KMSSink class to display the viewfinder stream, if any, through
DRM/KMS. The output connector is selected through the new -D/--display
argument.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Not all display controllers support enabling the display without any
active plane. Delay display enabling to the first frame.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Add a KMSSink class to display framebuffers through the DRM/KMS API.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
To prepare for viewfinder operation through the DRM/KMS API, add a set
of helper classes that encapsulate the libdrm functions.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Rename the BufferWriter class to FileSink to establish a common naming
scheme for all sinks.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
|
|
Make the BufferWriter class inherit from FrameSink, and use the
FrameSink API to manage it. This makes the code more generic, and will
allow usage of other sinks.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
|
|
The FrameSink class serves as a base to implement components that
consume frames. This allows handling frame sinks in a generic way,
independent of their nature. The BufferWrite class will be ported to
FrameSink in a second step.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
|
|
Extend the EventLoop class to support watching file descriptors for
read and write events.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
|
|
The std::cerr adjustment is set to std::left to print the usage text.
Restore it to its original value when done, to avoid affecting the
caller.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
The CamApp loopUsers_ member variable isn't initialized, which results
in random execution of the event loop. Fix it.
Fixes: caa6ffacb2fc ("cam: Reorganize run() function and merge the two event loops")
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
Tested-by: Umang Jain <umang.jain@ideasonboard.com>
|
|
To allow testing capture from multiple cameras concurrently, turn the
--camera option into an array option, and create one CameraSession per
specified camera. The code is adapted to iterate over the sessions
vector instead of handling a single session. Thanks to all the
refactoring previously performed, changes are minimal.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
To prepare for multi-camera support, extend the file naming scheme for
captured frames to include the camera index in addition to the stream
name and frame number.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Use the new hierarchical options feature of the option parser to turn
camera-related option (--capture, --file, --stream, --strict-formats and
--metadata) into children of the --camera option. As an added bonus, we
don't need to check anymore if a camera has been specified when capture
is requested, as that's now enforced by the option parser.
This change prepares for support of multiple cameras.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
The value of the --file option is the full name of the file to which
captured frames are written. To write files to a specific directory with
the default naming scheme, the "frame-#.bin" name has to appear at the
end of the file name. Simplify usage of the option by allowing --file to
specify a directory only. If the file name ends with a '/', the default
"frame-#.bin" file name is automatically appended.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Reorganize the run() function to make it more readable, and merge the
two event loops into one as capture and hotplug monitoring don't have to
be mutually exclusive.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
The session_ member of the CamApp class is only needed in the run()
function. Make it a local variable.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
The three CamApp functions listControls(), listProperties() and
infoConfiguration() operate on a camera. They would thus be better
placed in the CameraSession class. Move them there. As they now have no
error to return anymore, make them void functions.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Move creation of the camera session and setup of the hotplug monitoring
from the init() function to the run() function, to group all the code
that performs operations based on command line options in a single
place. The cleanup() call on session creation failure isn't required
anymore, as the cleanup() function is called unconditionally upon return
from run().
This change allows merging two different code blocks related to hotplug
monitoring.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
The CamApp::cameraName() doesn't need to access any member of the CamApp
class. Make it static. While at it, drop an unneeded const from the
return value.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
The EventLoop::exec() function returns the exit code of the event loop,
not an error status. Drop the corresponding error check and error
message.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Store the CameraManager instance in a unique_ptr to simplify memory
management and avoid leaks.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Continue moving towards making the CameraSession class the central point
to handle a camera by moving the camera acquire operation. A new
CameraSession::camera() function is needed to allow access to the camera
from CamApp.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Creating a configuration for a camera is an operation that logically
belongs to the CameraSession class. Move it there.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Move the local CameraSession variable from the CamApp::run() function to
a member variable of the CamApp class, created in CamApp::init(). This
is a first step towards moving code to the CameraSession class.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Store the BufferWriter and FrameBufferAllocator pointers in
std::unique_ptr<> instances to simplify memory management and avoid
leaks.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
To prepare for multiple concurrent camera sessions, move the event loop
exec() call from the CameraSession class to the CamApp class.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Make exiting the event loop the responsibility of the application, not
the camera session, to prepare for support of multiple camera sessions.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Don't pass the event loop to the CameraSession constructor, as passing
this global object explicitly isn't a design that can scale.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
Rename the Capture class to CameraSession, to prepare for multi-camera
support that will gather more camera-related operations than capture in
that class.
While at it, remove an unneeded blank line.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
|
|
The options parser currently ignores non-option arguments silently,
which is confusing. It's a common error to run 'cam -c1 -C 10' and
expect only 10 frames to be captured. As the -C option takes an optional
argument, the number 10 is interpreted as a non-option argument instead
of the argument to the -C option.
Fail parsing with an appropriate message and print usage information
when a non-option argument is found. The parser may be extended later to
accept non-option arguments when the application has a use for them.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
|
|
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>
|
|
To prepare for code reuse, split the printing of options out of
OptionsParser::usage() to a separate function.
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>
|
|
Before extending the option parser, document its existing API.
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>
|