summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2021-08-02android: capabilities: Make keys list into set and member variablePaul Elder
We need to be able to add additional characteristics/request/result keys into the corresponding list in the static metadata based on libcamera camera capabilities. We also need to be able to easily check if the lists have specific keys, for populating templates and result metadata. Turn the characteristics, requests, and results keys vectors into sets, and move them to member variables to achieve this. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-02android: Add helpers for setting android metadata from libcamera controlsPaul Elder
Add helpers for setting android metadata from libcamera controls. There are two versions, for scalars and collections, both of which take a default value to fill in the android control if the libcamera control is not found. They both return the value that was set. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-02android: Add infrastructure for determining capabilities and hardware levelPaul Elder
Add the infrastructure for checking and reporting capabilities. Use these capabilities to determine the hardware level as well. Bug: https://bugs.libcamera.org/show_bug.cgi?id=55 Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-02android: jpeg: get ISO from SENSOR_SENSITIVITYPaul Elder
The data for the exif ISO tag needs to come from SENSOR_SENSITIVITY. Set it. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-08-02android: metadata: Fix addEntry template typePaul Elder
Since we set entries with android tags directly, which are enums and not arithmetic types, the addEntry template fails to match. Fix this by also allowing enum values in addEntry. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-02android: metadata: Add hasEntry and entryContainsPaul Elder
Add convenience functions for checking if an entry is present in a CameraMetadata instance, and to check if an array entry includes a specific value. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-08-02controls: Add boolean constructors for ControlInfoPaul Elder
It would be convenient to be able to iterate over available boolean values, for example for controls that designate if some function can be enabled/disabled. The current min/max/def constructor is insufficient, as .values() is empty, so the values cannot be easily iterated over, and creating a Span of booleans does not work for the values constructor. Add new constructors to ControlInfo that takes a set of booleans (if both booleans are valid values) plus a default, and another that takes only one boolean (if only one boolean is a valid value). Update the ControlInfo test accordingly. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-08-02ipa: raspberrypi: Add support for imx378 sensorDavid Plowman
This commit adds a tuning file for the 12MP imx378 sensor. The sensor actually shares the same driver (and CamHelper) as the imx477 so only a new tuning file is required. The default choice of imx477.json can be overridden by pointing LIBCAMERA_RPI_TUNING_FILE at a version of the new imx378.json file. Signed-off-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.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>
2021-08-02utils: raspberrypi: ctt: Fix usage of findHomography functionDavid Plowman
The OpenCV findHomography function now raises an unhandled error if it receives fewer than 4 points whereas previously the limit was 3. This makes no material difference to the behaviour of the tuning tool as it will continue to search for the Macbeth chart at different scales. Signed-off-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.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>
2021-07-28ipa: raspberrypi: Return controls::FrameDuration from the IPANaushir Patuck
Return controls::FrameDuration through the per-frame Request metadata. The frame duration is obtained by either the value in DelayedControls, or (preferably) the value parsed from the embedded data buffer. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-07-28pipeline: raspberrypi: Fix a bug when clearing out Request buffers on stopNaushir Patuck
When RPiCameraData::clearIncompleteRequests() clears out the request queue during a stop condition, it unconditionally calls completeBuffer() on all buffers in each request. This is wrong, as a buffer could have already been completed as part of the current request, but the request itself may not yet have completed. Fix this by checking if the buffers in the request have been completed before cancelling them. Fixes: d372aaa10ddb ("pipeline: raspberrypi: Simplify RPiCameraData::clearIncompleteRequests()") Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Tested-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-07-28gstreamer: Store group_id in GstLibcameraSrcStateVedant Paranjape
This patch adds group_id in GstLibcameraSrcState, since group_id is something which should be same for all the pads, it can be reused later. Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
2021-07-27android: capabilities: Centralize RAW support checkJacopo Mondi
The validation of RAW stream support is performed in two different places: - At initializeStreamConfigurations() time, by verifying that the libcamera format associated with HAL_PIXEL_FORMAT_BLOB is a Raw format and ensuring the Camera successfully validates it - As initializeStaticMetadata() time by generating a CameraConfiguration for the Raw stream role and ensuring it is a Raw format with a 16 bit depth The first check is used to build the list of supported Raw stream resolutions. The latter is used to register the ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW capability. As building the list of supported Raw streams doesn't serve any purpose if the RAW capability is not registered, centralize the Raw format support verification at initializeStreamConfigurations() time by ensuring the supported format is a Raw one with a 16 bit depth. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-07-27android: capabilties: Rationalize get[YUV|Raw]Resolution namesJacopo Mondi
The getYUVResolutions() and getRawResolutions() functions are called from the initializeStreamConfigurations() function, which is called by initialize(). Rationalize the function naming scheme by renaming the two functions to initializeYUVResolutions() and initializeRawResolution(). Cosmetic change only. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-07-27android: capabilities: Use a throw-away config for YUV stream buildingJacopo Mondi
When building the list of supported YUV streams in getYUVResolutions() the CameraConfiguration provided by the caller as first parameters is used. As the CameraConfiguration will be later actually applied to the Camera, avoid any possible overlap of the configuration parameters by using a throw-away CameraConfiguration generated for the Viewfinder stream role in getYUVResolutions(). It's also nicer to avoid having two functions with a similar purpose such as getYUVResolutions() and getRawResolutions() with different parameter lists, as the presence of a CameraConfiguration as first parameter might be confusing to the reader. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
2021-07-27ipa: core.mojom: Rework core file documentationJacopo Mondi
The comment block at the beginning of the core.mojom file is meant to provide an overview of how to use libcamera defined types in the definition of mojom interfaces. As the IPA/IPC interface definition mechanism evolved, the documentation has not been updated accordingly. Update the file comments to match the most recent IPA/IPC interface definition and generation mechanism. Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-07-27cam: options: Restore std::cerr adjustment fieldLaurent Pinchart
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>
2021-07-27utils: ipc: Assign a new gid to proxy workerUmang Jain
Isolated IPAs are forked to a new process by the proxy worker, which shares the same process group. This allows the undesired effect that the proxy worker will receive signals such as SIGINT and will be closed by a Ctrl-C event before the pipeline handlers have been able to fully clean up. Prevent this signal from being delivered to the proxy worker by moving the process to a new process group, matching the pid of the isolated proxy. Bug: https://bugs.libcamera.org/show_bug.cgi?id=60 Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
2021-07-26libcamera: CameraSensorProperties: Sort entriesLaurent Pinchart
Keep entries sorted by sensor name to ensure the file stays readable. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-07-25libcamera: Add OV8865 sensor propertiesDaniel Scally
Add camera sensor properties for the OV8865 sensor. This is the world facing camera on most MS Surface platforms. Signed-off-by: Daniel Scally <djrscally@gmail.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-07-25libipa: Add CameraSensorHelper for ov8865Daniel Scally
Add a CameraSensorHelperOv8865 class. The gain coefficients are gleaned from the datasheet; the lowest 7 bits are reported there as fractional bits, so real gain is val/128. Signed-off-by: Daniel Scally <djrscally@gmail.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-07-23libipa: Add CameraSensorHelper for IMX258Umang Jain
Extend the CameraSensorHelper factory with support for the IMX258 sensor found in the Nautilus Chromebook. The values are read by manually tweaking the IMX258 kernel driver. The IMX258 kernel driver hints that the sensor may be compatible with the MIPI CCS specification, as the register set matches. The values for analog gain constants are obtained by reading the register indexes, corresponding to the analog gain constants, as mentioned in MIPI CCS v1.1 specification. The values have further been confirmed by Dave Stevenson as being those specified in the datasheet. Signed-off-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-07-23cam: Initialize CamApp::loopUsers_Laurent Pinchart
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>
2021-07-22cam: Support using multiple cameras concurrentlyLaurent Pinchart
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>
2021-07-22cam: Add camera index to file name of capture framesLaurent Pinchart
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>
2021-07-22cam: Make camera-related options sub-options of OptCameraLaurent Pinchart
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>
2021-07-22cam: Allow specifying directories in the --file optionLaurent Pinchart
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>
2021-07-22cam: Reorganize run() function and merge the two event loopsLaurent Pinchart
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>
2021-07-22cam: Move session_ member variable to a local variable in run() functionLaurent Pinchart
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>
2021-07-22cam: Move printing of camera information to CameraSession classLaurent Pinchart
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>
2021-07-22cam: Move camera session creation and monitoring setup to run()Laurent Pinchart
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>
2021-07-22cam: Make CamApp::cameraName() staticLaurent Pinchart
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>
2021-07-22cam: Drop unneeded error check and messageLaurent Pinchart
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>
2021-07-22cam: Use std::unique_ptr<> to manage CameraManagerLaurent Pinchart
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>
2021-07-22cam: Move camera acquire to the CameraSession classLaurent Pinchart
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>
2021-07-22cam: Move CameraConfiguration creation to CameraSession classLaurent Pinchart
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>
2021-07-22cam: Store camera session pointer in CamApp classLaurent Pinchart
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>
2021-07-22cam: camera_session: Use std::unique_ptr<> to manage class membersLaurent Pinchart
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>
2021-07-22cam: Move event loop execution from CameraSession to CamAppLaurent Pinchart
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>
2021-07-22cam: Move event loop exit from CameraSession to CamAppLaurent Pinchart
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>
2021-07-22cam: camera_session: Access event loop through global instanceLaurent Pinchart
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>
2021-07-22cam: Rename Capture to CameraSessionLaurent Pinchart
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>
2021-07-22cam: options: Fail parsing when non-option arguments are foundLaurent Pinchart
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>
2021-07-22cam: options: Avoid copies of OptionvValue and KeyValueParser::OptionsLaurent Pinchart
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>
2021-07-22cam: stream_options: Use OptionValue::empty() to test if option is setLaurent Pinchart
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>
2021-07-22cam: options: Add empty() function to OptionValue classLaurent Pinchart
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>
2021-07-22cam: options: Drop some OptionValue cast operatorsLaurent Pinchart
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>
2021-07-22cam: options: Support parent-child relationship between optionsLaurent Pinchart
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>
2021-07-22cam: options: Move key string left in usage() for key-value parserLaurent Pinchart
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>
2021-07-22cam: options: Disable copy for parsersLaurent Pinchart
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>
*/ /** * \brief Bound the size down to match the aspect ratio given by \a ratio * \param[in] ratio The size whose aspect ratio must be matched * * The behaviour of this function is undefined if either the width or the * height of the \a ratio is zero. * * \return A Size whose width and height are equal to the width and height * of this Size aligned down to the aspect ratio of \a ratio */ Size Size::boundedToAspectRatio(const Size &ratio) const { ASSERT(ratio.width && ratio.height); uint64_t ratio1 = static_cast<uint64_t>(width) * static_cast<uint64_t>(ratio.height); uint64_t ratio2 = static_cast<uint64_t>(ratio.width) * static_cast<uint64_t>(height); if (ratio1 > ratio2) return { static_cast<unsigned int>(ratio2 / ratio.height), height }; else return { width, static_cast<unsigned int>(ratio1 / ratio.width) }; } /** * \brief Expand the size to match the aspect ratio given by \a ratio * \param[in] ratio The size whose aspect ratio must be matched * * The behaviour of this function is undefined if either the width or the * height of the \a ratio is zero. * * \return A Size whose width and height are equal to the width and height * of this Size expanded up to the aspect ratio of \a ratio */ Size Size::expandedToAspectRatio(const Size &ratio) const { ASSERT(ratio.width && ratio.height); uint64_t ratio1 = static_cast<uint64_t>(width) * static_cast<uint64_t>(ratio.height); uint64_t ratio2 = static_cast<uint64_t>(ratio.width) * static_cast<uint64_t>(height); if (ratio1 < ratio2) return { static_cast<unsigned int>(ratio2 / ratio.height), height }; else return { width, static_cast<unsigned int>(ratio1 / ratio.width) }; } /** * \brief Center a rectangle of this size at a given Point * \param[in] center The center point the Rectangle is to have * * A Rectangle of this object's size is positioned so that its center * is at the given Point. * * \return A Rectangle of this size, centered at the given Point. */ Rectangle Size::centeredTo(const Point &center) const { int x = center.x - width / 2; int y = center.y - height / 2; return { x, y, width, height }; } /** * \brief Scale size up by the given factor * \param[in] factor The factor * \return The scaled Size */ Size Size::operator*(float factor) const { return Size(width * factor, height * factor); } /** * \brief Scale size down by the given factor * \param[in] factor The factor * \return The scaled Size */ Size Size::operator/(float factor) const { return Size(width / factor, height / factor); } /** * \brief Scale this size up by the given factor in place * \param[in] factor The factor * \return A reference to this object */ Size &Size::operator*=(float factor) { width *= factor; height *= factor; return *this; } /** * \brief Scale this size down by the given factor in place * \param[in] factor The factor * \return A reference to this object */ Size &Size::operator/=(float factor) { width /= factor; height /= factor; return *this; } /** * \brief Compare sizes for equality * \return True if the two sizes are equal, false otherwise */ bool operator==(const Size &lhs, const Size &rhs) { return lhs.width == rhs.width && lhs.height == rhs.height; } /** * \brief Compare sizes for smaller than order * * Sizes are compared on three criteria, in the following order. * * - A size with smaller width and smaller height is smaller. * - A size with smaller area is smaller. * - A size with smaller width is smaller. * * \return True if \a lhs is smaller than \a rhs, false otherwise */ bool operator<(const Size &lhs, const Size &rhs) { if (lhs.width < rhs.width && lhs.height < rhs.height) return true; else if (lhs.width >= rhs.width && lhs.height >= rhs.height) return false; uint64_t larea = static_cast<uint64_t>(lhs.width) * static_cast<uint64_t>(lhs.height); uint64_t rarea = static_cast<uint64_t>(rhs.width) * static_cast<uint64_t>(rhs.height); if (larea < rarea) return true; else if (larea > rarea) return false; return lhs.width < rhs.width; } /** * \fn bool operator!=(const Size &lhs, const Size &rhs) * \brief Compare sizes for inequality * \return True if the two sizes are not equal, false otherwise */ /** * \fn bool operator<=(const Size &lhs, const Size &rhs) * \brief Compare sizes for smaller than or equal to order * \return True if \a lhs is smaller than or equal to \a rhs, false otherwise * \sa bool operator<(const Size &lhs, const Size &rhs) */ /** * \fn bool operator>(const Size &lhs, const Size &rhs) * \brief Compare sizes for greater than order * \return True if \a lhs is greater than \a rhs, false otherwise * \sa bool operator<(const Size &lhs, const Size &rhs) */ /** * \fn bool operator>=(const Size &lhs, const Size &rhs) * \brief Compare sizes for greater than or equal to order * \return True if \a lhs is greater than or equal to \a rhs, false otherwise * \sa bool operator<(const Size &lhs, const Size &rhs) */ /** * \brief Insert a text representation of a Size into an output stream * \param[in] out The output stream * \param[in] s The size * \return The output stream \a out */ std::ostream &operator<<(std::ostream &out, const Size &s) { out << s.width << "x" << s.height; return out; } /** * \struct SizeRange * \brief Describe a range of sizes * * A SizeRange describes a range of sizes included in the [min, max] interval * for both the width and the height. If the minimum and maximum sizes are * identical it represents a single size. * * Size ranges may further limit the valid sizes through steps in the horizontal * and vertical direction. The step values represent the increase in pixels * between two valid width or height values, starting from the minimum. Valid * sizes within the range are thus expressed as * * width = min.width + hStep * x * height = min.height + vStep * y * * Where * * width <= max.width * height < max.height * * Note that the step values are not equivalent to alignments, as the minimum * width or height may not be a multiple of the corresponding step. * * The step values may be zero when the range describes only minimum and * maximum sizes without implying that all, or any, intermediate size is valid. * SizeRange instances the describe a single size have both set values set to 1. */ /** * \fn SizeRange::SizeRange() * \brief Construct a size range initialized to 0 */ /** * \fn SizeRange::SizeRange(const Size &size) * \brief Construct a size range representing a single size * \param[in] size The size */ /** * \fn SizeRange::SizeRange(const Size &minSize, const Size &maxSize) * \brief Construct a size range with specified min and max, and steps of 1 * \param[in] minSize The minimum size * \param[in] maxSize The maximum size */ /** * \fn SizeRange::SizeRange(const Size &minSize, const Size &maxSize, * unsigned int hstep, unsigned int vstep) * \brief Construct a size range with specified min, max and step * \param[in] minSize The minimum size * \param[in] maxSize The maximum size * \param[in] hstep The horizontal step * \param[in] vstep The vertical step */ /** * \var SizeRange::min * \brief The minimum size */ /** * \var SizeRange::max * \brief The maximum size */ /** * \var SizeRange::hStep * \brief The horizontal step */ /** * \var SizeRange::vStep * \brief The vertical step */ /** * \brief Test if a size is contained in the range * \param[in] size Size to check * \return True if \a size is contained in the range */ bool SizeRange::contains(const Size &size) const { if (size.width < min.width || size.width > max.width || size.height < min.height || size.height > max.height || (hStep && (size.width - min.width) % hStep) || (vStep && (size.height - min.height) % vStep)) return false; return true; } /** * \brief Assemble and return a string describing the size range * \return A string describing the SizeRange */ std::string SizeRange::toString() const { std::stringstream ss; ss << *this; return ss.str(); } /** * \brief Compare size ranges for equality * \return True if the two size ranges are equal, false otherwise */ bool operator==(const SizeRange &lhs, const SizeRange &rhs) { return lhs.min == rhs.min && lhs.max == rhs.max; } /** * \fn bool operator!=(const SizeRange &lhs, const SizeRange &rhs) * \brief Compare size ranges for inequality * \return True if the two size ranges are not equal, false otherwise */ /** * \brief Insert a text representation of a SizeRange into an output stream * \param[in] out The output stream * \param[in] sr The size range * \return The output stream \a out */ std::ostream &operator<<(std::ostream &out, const SizeRange &sr) { out << "(" << sr.min << ")-(" << sr.max << ")/(+" << sr.hStep << ",+" << sr.vStep << ")"; return out; } /** * \struct Rectangle * \brief Describe a rectangle's position and dimensions * * Rectangles are used to identify an area of an image. They are specified by * the coordinates of top-left corner and their horizontal and vertical size. * * The measure unit of the rectangle coordinates and size, as well as the * reference point from which the Rectangle::x and Rectangle::y displacements * refers to, are defined by the context were rectangle is used. */ /** * \fn Rectangle::Rectangle() * \brief Construct a Rectangle with all coordinates set to 0 */ /** * \fn Rectangle::Rectangle(int x, int y, const Size &size) * \brief Construct a Rectangle with the given position and size * \param[in] x The horizontal coordinate of the top-left corner * \param[in] y The vertical coordinate of the top-left corner * \param[in] size The size */ /** * \fn Rectangle::Rectangle(int x, int y, unsigned int width, unsigned int height) * \brief Construct a Rectangle with the given position and size * \param[in] x The horizontal coordinate of the top-left corner * \param[in] y The vertical coordinate of the top-left corner * \param[in] width The width * \param[in] height The height */ /** * \fn Rectangle::Rectangle(const Size &size) * \brief Construct a Rectangle of \a size with its top left corner located * at (0,0) * \param[in] size The desired Rectangle size */ /** * \var Rectangle::x * \brief The horizontal coordinate of the rectangle's top-left corner */ /** * \var Rectangle::y * \brief The vertical coordinate of the rectangle's top-left corner */ /** * \var Rectangle::width * \brief The distance between the left and right sides */ /** * \var Rectangle::height * \brief The distance between the top and bottom sides */ /** * \fn bool Rectangle::isNull() const * \brief Check if the rectangle is null * \return True if both the width and height are 0, or false otherwise */ /** * \brief Assemble and return a string describing the rectangle * \return A string describing the Rectangle */ const std::string Rectangle::toString() const { std::stringstream ss; ss << *this; return ss.str(); } /** * \brief Retrieve the center point of this rectangle * \return The center Point */ Point Rectangle::center() const { return { x + static_cast<int>(width / 2), y + static_cast<int>(height / 2) }; } /** * \fn Size Rectangle::size() const * \brief Retrieve the size of this rectangle * \return The Rectangle size */ /** * \fn Point Rectangle::topLeft() const * \brief Retrieve the coordinates of the top left corner of this Rectangle * \return The Rectangle's top left corner */ /** * \brief Apply a non-uniform rational scaling in place to this Rectangle * \param[in] numerator The numerators of the x and y scaling factors * \param[in] denominator The denominators of the x and y scaling factors * * A non-uniform scaling is applied in place such the resulting x * coordinates are multiplied by numerator.width / denominator.width, * and similarly for the y coordinates (using height in place of width). * * \return A reference to this object */ Rectangle &Rectangle::scaleBy(const Size &numerator, const Size &denominator) { x = static_cast<int64_t>(x) * numerator.width / denominator.width; y = static_cast<int64_t>(y) * numerator.height / denominator.height; width = static_cast<uint64_t>(width) * numerator.width / denominator.width; height = static_cast<uint64_t>(height) * numerator.height / denominator.height; return *this; } /** * \brief Translate this Rectangle in place by the given Point * \param[in] point The amount to translate the Rectangle by * * The Rectangle is translated in the x-direction by the point's x coordinate * and in the y-direction by the point's y coordinate. * * \return A reference to this object */ Rectangle &Rectangle::translateBy(const Point &point) { x += point.x; y += point.y; return *this; } /** * \brief Calculate the intersection of this Rectangle with another * \param[in] bound The Rectangle that is intersected with this Rectangle * * This function calculates the standard intersection of two rectangles. If the * rectangles do not overlap in either the x or y direction, then the size * of that dimension in the result (its width or height) is set to zero. Even * when one dimension is set to zero, note that the other dimension may still * have a positive value if there was some overlap. * * \return A Rectangle that is the intersection of the input rectangles */ Rectangle Rectangle::boundedTo(const Rectangle &bound) const { int topLeftX = std::max(x, bound.x); int topLeftY = std::max(y, bound.y); int bottomRightX = std::min<int>(x + width, bound.x + bound.width); int bottomRightY = std::min<int>(y + height, bound.y + bound.height); unsigned int newWidth = std::max(bottomRightX - topLeftX, 0); unsigned int newHeight = std::max(bottomRightY - topLeftY, 0); return { topLeftX, topLeftY, newWidth, newHeight }; } /** * \brief Enclose a Rectangle so as not to exceed another Rectangle * \param[in] boundary The limit that the returned Rectangle will not exceed * * The Rectangle is modified so that it does not exceed the given \a boundary. * This process involves translating the Rectangle if any of its edges * lie beyond \a boundary, so that those edges then lie along the boundary * instead. * * If either width or height are larger than \a boundary, then the returned * Rectangle is clipped to be no larger. But other than this, the * Rectangle is not clipped or reduced in size, merely translated. * * Note that this is not a conventional Rectangle intersection function * which is provided by boundedTo(). * * \return A Rectangle that does not extend beyond a boundary Rectangle */ Rectangle Rectangle::enclosedIn(const Rectangle &boundary) const { /* We can't be bigger than the boundary rectangle. */ Rectangle result = boundedTo(Rectangle{ x, y, boundary.size() }); result.x = std::clamp<int>(result.x, boundary.x, boundary.x + boundary.width - result.width); result.y = std::clamp<int>(result.y, boundary.y, boundary.y + boundary.height - result.height); return result; } /** * \brief Apply a non-uniform rational scaling to this Rectangle * \param[in] numerator The numerators of the x and y scaling factors * \param[in] denominator The denominators of the x and y scaling factors * * A non-uniform scaling is applied such the resulting x * coordinates are multiplied by numerator.width / denominator.width, * and similarly for the y coordinates (using height in place of width). * * \return The non-uniformly scaled Rectangle */ Rectangle Rectangle::scaledBy(const Size &numerator, const Size &denominator) const { int scaledX = static_cast<int64_t>(x) * numerator.width / denominator.width; int scaledY = static_cast<int64_t>(y) * numerator.height / denominator.height; unsigned int scaledWidth = static_cast<uint64_t>(width) * numerator.width / denominator.width; unsigned int scaledHeight = static_cast<uint64_t>(height) * numerator.height / denominator.height; return { scaledX, scaledY, scaledWidth, scaledHeight }; } /** * \brief Translate a Rectangle by the given amounts * \param[in] point The amount to translate the Rectangle by * * The Rectangle is translated in the x-direction by the point's x coordinate * and in the y-direction by the point's y coordinate. * * \return The translated Rectangle */ Rectangle Rectangle::translatedBy(const Point &point) const { return { x + point.x, y + point.y, width, height }; } /** * \brief Compare rectangles for equality * \return True if the two rectangles are equal, false otherwise */ bool operator==(const Rectangle &lhs, const Rectangle &rhs) { return lhs.x == rhs.x && lhs.y == rhs.y && lhs.width == rhs.width && lhs.height == rhs.height; } /** * \fn bool operator!=(const Rectangle &lhs, const Rectangle &rhs) * \brief Compare rectangles for inequality * \return True if the two rectangles are not equal, false otherwise */ /** * \brief Insert a text representation of a Rectangle into an output stream * \param[in] out The output stream * \param[in] r The rectangle * \return The output stream \a out */ std::ostream &operator<<(std::ostream &out, const Rectangle &r) { out << "(" << r.x << ", " << r.y << ")/" << r.width << "x" << r.height; return out; } } /* namespace libcamera */