summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2021-01-23libcamera: Rename wrong header guards for internal includesLaurent Pinchart
Some internals includes that used to be public still have the public header guard. Rename it. 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> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2021-01-22android: camera_device: Clone settings in request descriptorJacopo Mondi
When a Camera3RequestDescriptor instance is created to wrap a camera3_capture_request_t the settings associated with the request are cloned for later re-use. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-22android: camera_metadata: Add defaul constructorJacopo Mondi
Add a default constructor that initializes a non valid CameraMetadata to allow embedding instances of the class in other types. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-22android: camera_device: Copy camera3 buffers in descriptorJacopo Mondi
The camera3_stream_buffer_t instances part of a capture request contain information on the stream for which capture has been requested (size, format and fences) and a handle to the stream's memory buffers. This information is copied in the descriptor one piece at the time while processing the camera3 streams to be re-used at request completion time. Simplify the code by copying the stream information in the descriptor at construction time. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-22android: camera_device: Pass camera3 request to descriptorJacopo Mondi
The Camera3RequestDescriptor class can access the number of buffers and the frame number from the camera3_capture_request_t instead of having the caller passing them to the constructor. This change allows to access other fields of the capture request, such as the capture settings. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-22android: camera_metadata: Add copy constructor and getEntryPaul Elder
Add a copy constructor and assignment operator to CameraMetadata, as well a constructor from camera_metadata_t. Also add a function getEntry to allow getting metadata entries from CameraMetadata. This allows us to use CameraMetadata for reading from camera_metadata_t. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-21utils: checkstyle.py: Fix "protected" members in Commit classLaurent Pinchart
The Commit class and subclasses were reworked in commit 4f5d17f3a4f5 ("utils: checkstyle.py: Make title and files properties of commit class") with the introduction of members of the base class that were meant to be protected (not used externally, but accessible by subclasses). They have been named with a '__' prefix for this purpose, which was a bad choice as Python effectively replaces a leading '__' with a literal '__classname__' prefix to make them private (https://docs.python.org/3/tutorial/classes.html#private-variables). The members accessed in the derived classes are thus different from the ones in the base class. Fix this by replacing the double underscore prefix with a single underscore, which is a "weak internal use indicator" (as specified in https://www.python.org/dev/peps/pep-0008/), closer to the protected access specifier of C++. Reported-by: Umang Jain <email@uajain.com> Reported-by: Naushir Patuck <naush@raspberrypi.com> Fixes: 4f5d17f3a4f5 ("utils: checkstyle.py: Make title and files properties of commit class") Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Tested-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
2021-01-20libcamera: Use meson summary() function to summarize configurationLaurent Pinchart
Now that Debian backports have been updated to meson v0.56, all major distributions provide meson >= v0.53 in their latest LTS version. We can replace the manual message()-based configuration summary with the summary() function. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Sebastian Fricke <sebastian.fricke@posteo.net> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-01-20ipa: raspberrypi: config: Update shutter speeds for imx219/477 and ov5647Naushir Patuck
Set the maximum shutter speed for the normal exposure profile to 66ms, allowing viewfinder framerates to go down to approx. 15fps. Set the maximum shutter speed for the sport exposure profile to 33ms, limiting the minimum framerate to approx. 30fps. Add a long exposure profile to allow shutter speeds of up to 120ms. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Tested-by: David Plowman <david.plowman@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-01-20libcamera: raspberrypi: Add control of sensor vblankingNaushir Patuck
Add support for setting V4L2_CID_VBLANK appropriately when setting V4L2_CID_EXPOSURE. This will allow adaptive framerates during viewfinder use cases (e.g. when the exposure time goes above 33ms, we can reduce the framerate to lower than 30fps). The minimum and maximum frame durations are provided via libcamera controls, and will prioritise exposure time limits over any AGC request. V4L2_CID_VBLANK is controlled through the staggered writer, just like the exposure and gain controls. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Tested-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-01-20libcamera: controls: Add frame duration controlNaushir Patuck
Add an int64_t array control (controls::FrameDurations) to specify the minimum and maximum (in that order) frame duration to be used by the camera sensor. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Tested-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2021-01-20Documentation: sensor-driver: Correct camera rotationJacopo Mondi
The description of the V4L2_CID_CAMERA_SENSOR_ROTATION control usage wrongly mentioned the camera "orientation" while it actually reports the camera rotation. Fix it by using the right term. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reported-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-20Documentation: sensor-drivers: Reorder introductionJacopo Mondi
Reorder the introductory section of the sensor driver requirements document to match the expected English language syntax. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Suggested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-18android: camera_device: Do not default pixel array propertiesJacopo Mondi
Now that the pixel array properties have been defaulted in the CameraSensor class (or in the pipeline handler, for the UVC use case), they will always be reported by the libcamera::Camera and there's no need to default them in the Camera HAL. Remove defaults and assume properties are always there. Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-18libcamera: camera_sensor: Initialize VIMC propertiesJacopo Mondi
The VIMC driver does not yet support all the features required for all sensor drivers. As it is the main testing platforms and the driver changes might take a long time to land in the developments and testing platforms, temporary close the gap by skipping driver validation and initializing properties with static information such as the sensor resolution. Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-18libcamera: media_object: Add a const version of dev()Jacopo Mondi
Add a const version of the MediaObject::dev() method to be able to retrieve a pointer to a const MediaDevice from a constant instance of a MediaObject sub-class. Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-18libcamera: uvc: Initialize the pixel array propertiesJacopo Mondi
Initialize the pixel array properties in the UVC pipeline handler as they're now initialized in the CameraSensor class, which the UVC pipeline handler does not use. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-18libcamera: camera_sensor: Do not default 'rotation'Jacopo Mondi
The 'rotation' property is not critical. Only register it if the sensor driver reports it. Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-18libcamera: camera_sensor: Default 'location' to ExternalJacopo Mondi
If the sensor driver does not report the camera location default it to 'External' instead of 'Front'. As the camera location is used to construct the camera unique name presented to the user, it makes more sense to report multiple 'External' cameras instead of multiple 'Front' ones. Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-18libcamera: camera_sensor: Default analogue crop rectangleJacopo Mondi
As support for the V4L2_SEL_TGT_CROP selection target used to read the sensor analogue crop rectangle is schedule to become mandatory but is still optional, use the sensor's active area size as fallback value to allow the creation of the CameraSensorInfo in the case the driver does not support it. Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-18libcamera: camera_sensor: Provide fall-back for sensor propertiesJacopo Mondi
Support for the V4L2 selection API is currently optional in the CameraSensor class. Properties registered by using values read through that API are defaulted in several different places (the Android camera HAL or the CameraSensor class). In the future support for the selection API will be made mandatory, but to give time to sensor drivers in all test platforms to be updated, use sensor resolution as fallback values for sensor pixel array properties and cache them as class member variables. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-18libcamera: camera_sensor: Validate driver supportJacopo Mondi
The CameraSensor class requires the sensor driver to report information through V4L2 controls and through the V4L2 selection API, and uses that information to register Camera properties and to construct CameraSensorInfo class instances to provide them to the IPA. Currently, validation of the kernel support happens each time a feature is requested, with slighly similar debug/error messages output to the user in case a feature is not supported. Rationalize this by validating the sensor driver requirements in a single function Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-18libcamera: Document sensor driver requirementsJacopo Mondi
Document the feature an image sensor driver has to provide to be fully libcamera-compliant. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2021-01-13libcamera: sysfs: Fix directory exists checkNiklas Söderlund
The scope of File::exists() was changed to only validate that a file exists and is therefore not usable to check if a directory exists. This breaks the persistent name generation for DT based systems as it uses File::exists() to check for directories, fix this by using stat() directly. On Scarlet the persistent names of the cameras are impacted by this and where incorrectly reported as: $ cam -l Available cameras: 1: Internal front camera (platform/ff160000.i2c/i2c-7/7-003c ov2685) 2: Internal front camera (platform/ff160000.i2c/i2c-7/7-0036 ov5695 While the expected ones are restored with this fix: $ cam -l Available cameras: 1: Internal front camera (/base/i2c@ff160000/camera@3c) 2: Internal front camera (/base/i2c@ff160000/camera@36) Fixes: 8f4e16f014c820a0 ("test: file: Check that directories are not treated as files") Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-01-12libcamera: pipelines: ipu3: Simplify error bail out path on start()Umang Jain
On the bail out path, always ensure that ImgU and CIO2 are stopped before freeing the buffers. V4L2VideoDevice class guarantees that calling stop() without having to call start() is harmless, hence use this guarantee to simplify error paths. Signed-off-by: Umang Jain <email@uajain.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-01-12libcamera: v4l2_videodevice: Track streaming stateKieran Bingham
Track the state of streamon/streamoff calls to simplify error paths. Ensuring that streamOff() can be called on non-streaming streams facilitates simpler error code paths, where a set of devices can all call streamOff regardless of their initialisation state. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Umang Jain <email@uajain.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-01-05libcamera: camera: Fix-typoSebastian Fricke
s/chance/change/ Signed-off-by: Sebastian Fricke <sebastian.fricke.linux@gmail.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2021-01-04android: camera_device: Only advertise RAW support if RAW16 is availableNiklas Söderlund
The Android camera2 API defines a RAW capture capability ([1]) for devices that support "outputting RAW buffers and metadata for interpreting them". This capability requires the camera device to support RAW_SENSOR ([2]) as an output format. Despite what its name may sound like, the RAW_SENSOR format is defined as a 16 bits RAW format, not an opaque implementation-dependent format (which is instead called RAW_PRIVATE). Devices may additionally support the RAW10 and RAW12 formats, but that isn't enough to claim RAW capture capability. To comply with the API requirements, only report the ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW capability when 16-bit RAW is supported. [1] https://developer.android.com/reference/android/hardware/camera2/CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_RAW [2] https://developer.android.com/reference/android/graphics/ImageFormat#RAW_SENSOR Suggested-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-12-30src: meson: Simplify v4l2 enablementKieran Bingham
Simplify the src level meson file by moving the declaration of the v4l2 subdir to match the other invocations, making use of 'subdir_done()' to break out if the adaptation layer is not enabled. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-12-30src: meson: Re-order subdir layoutKieran Bingham
Move the android subdir below the configuration options to keep all subdirs together. Add a comment explaining why android must come first, and some padding to group the libcamera and ipa components, applications, and remaining adaptation layers. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-12-30meson: test: Simplify top level mesonKieran Bingham
Utilise the subdir_done() functionality as is used with other optional components to simplify the top level meson file. Suggested-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-12-30libcamera: file: Check files exist()Kieran Bingham
Ensure that when we check for existence with File() it will only return if the path leads to a file, and not a directory. Device nodes which could still be opened by this class are still supported. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-12-30test: file: Check that directories are not treated as filesKieran Bingham
Directories can not be opened as a file, so the exists() check should not return true for a path which points to a directory. Directories are not handled by the File class. Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-12-30android: camera_device: Simplify properties.get()Jacopo Mondi
When accessing the value of a property by reading the properties ControlList content with ControlList::get<>() it is not necessary to specify the template type as it is already conveyed by the Control instance provided as first argument. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2020-12-30android: camera_device: Report ColorFilterArrangementJacopo Mondi
Conditionally report the ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT property inspecting the draft property reported by the libcamera Camera. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2020-12-30libcamera: camera_sensor: Register ColorFilterArrangementJacopo Mondi
Inspect the list of media bus codes supported by the camera sensor in order to deduce the color filter arrangement and register the ColorFilterArrangement draft property. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2020-12-30libcamera: bayer_format: Add support for mbus codesJacopo Mondi
The existing implementation of the BayerFormat class supports converting a V4L2PixelFormat to a BayerFormat and vice-versa. Expand the class by adding support for converting a media bus code to a BayerFormat instance, by providing a conversion table and a dedicated static methods. Do not provide support for converting a BayerFormat to a media bus code as there's no 1-to-1 mapping between the two. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2020-12-30libcamera: properties: ColorFilterArrangement draft propertyJacopo Mondi
Define the 'ColorFilterArrangement' draft property. The property is currently identical to ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT. Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2020-12-29utils: checkstyle.py: Drop astyle supportLaurent Pinchart
Formatting code using astyle doesn't lead to results as good as with clang-format, and doesn't receive much test coverage as most developers use clang-format. The code is thus bitrotting. Drop it. 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>
2020-12-29utils: checkstyle.py: Add header add checkerLaurent Pinchart
Add a commit checker that ensures that all header files added to the libcamera includes (public or internal) are accompanied by a corresponding update of the meson.build file in the same directory. Here's the output of the new checker when run against a commit that forgot to update meson.build. $ ./utils/checkstyle.py b3383da79f1d --------------------------------------------------------------------------------- b3383da79f1d513b0d76db220a7104e1c1035e30 libcamera: buffer: Create a MappedBuffer --------------------------------------------------------------------------------- Header include/libcamera/internal/buffer.h added without corresponding update to include/libcamera/internal/meson.build --- 1 potential issue detected, please review In theory we could extend the checker to cover .cpp files too, but the issue will be quite noticeable as meson won't build the file if meson.build isn't updated. Header files are more tricky as problems would only occur at when installing the headers (for public headers), or would result in race conditions in the build. Both of those issues are harder to catch. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-12-29utils: checkstyle.py: Add commit checkersLaurent Pinchart
Add a new category of checkers that operate on a whole commit. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-12-29utils: checkstyle.py: Move diff parsing to Commit classLaurent Pinchart
To avoid duplicating diff parsing in commit checkers, move it to the Commit class. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-12-29utils: checkstyle.py: Add ability to filter files by status in a commitLaurent Pinchart
A commit can perform different operations on a file. Record the file status (added, modified, renamed, deleted, ...) and add the ability to filter files by status when listing the files touched by a commit. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-12-29utils: checkstyle.py: Make title and files properties of commit classLaurent Pinchart
Make the API of the Commit class more explicit by exposing the title and files as properties instead of through a get_info() method. 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>
2020-12-29utils: checkstyle.py: Move commit handling to a separate sectionLaurent Pinchart
To prepare for checkers that operate directly on commits, move the related classes to a separate section. No functional change is included. 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>
2020-12-29utils: checkstyle.py: Factor out automatic class registryLaurent Pinchart
The style checkers and formatters duplicate automatic class registry code. Factor it out to a common ClassRegistry helper class. The list of subclasses is moved to a class member variable of the auto-registered base class type. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-12-29utils: checkstyle.py: Drop arguments to super() when possibleLaurent Pinchart
The super() call is a shortcut syntax for super(__class__, <first arg>). Drop the arguments when they match the default. 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>
2020-12-28libcamera: pipeline_handler: Remove Camera pointer from CameraDataNiklas Söderlund
There are no users left of this field, drop it. 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>
2020-12-28libcamera: pipeline_handler: Remove Camera argument from request handlingNiklas Söderlund
There is no need to pass the Camera pointer to queueRequest(), completeBuffer() and completeRequest() as the Request also passed contains the same information. Remove the Camera argument to avoid situations where the information in the Request and the argument differ. There is no functional change and no public API change as the interface is only used between the Camera and PipelineHandler. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-12-27Documentation: Fix Doxygen exclusion of details namespacesLaurent Pinchart
The details namespaces in libcamera are used to hide implementation details, and should thus be excluded from documentation generation. This is done incorrectly by specifying the exclusion pattern "*::details::*" which will ignore all namespaces and types in any details namespace, but won't ignore functions. Fix it by removing the trailing "::*", causing Doxygen to ignore the namespace itself, and thus all its contents. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
ss="hl opt">(&ctrls); /* Enumerate, sort and cache media bus codes and sizes. */ formats_ = subdev_->formats(pad_); if (formats_.empty()) { LOG(CameraSensor, Error) << "No image format found"; return -EINVAL; } mbusCodes_ = utils::map_keys(formats_); std::sort(mbusCodes_.begin(), mbusCodes_.end()); for (const auto &format : formats_) { const std::vector<SizeRange> &ranges = format.second; std::transform(ranges.begin(), ranges.end(), std::back_inserter(sizes_), [](const SizeRange &range) { return range.max; }); } std::sort(sizes_.begin(), sizes_.end()); /* Remove duplicates. */ auto last = std::unique(sizes_.begin(), sizes_.end()); sizes_.erase(last, sizes_.end()); /* * VIMC is a bit special, as it does not yet support all the mandatory * requirements regular sensors have to respect. * * Do not validate the driver if it's VIMC and initialize the sensor * properties with static information. * * \todo Remove the special case once the VIMC driver has been * updated in all test platforms. */ if (entity_->device()->driver() == "vimc") { initVimcDefaultProperties(); return initProperties(); } /* Get the color filter array pattern (only for RAW sensors). */ for (unsigned int mbusCode : mbusCodes_) { const BayerFormat &bayerFormat = BayerFormat::fromMbusCode(mbusCode); if (bayerFormat.isValid()) { bayerFormat_ = &bayerFormat; break; } } ret = validateSensorDriver(); if (ret) return ret; ret = initProperties(); if (ret) return ret; ret = discoverAncillaryDevices(); if (ret) return ret; return applyTestPatternMode(controls::draft::TestPatternModeEnum::TestPatternModeOff); } int CameraSensor::validateSensorDriver() { int err = 0; /* * Optional controls are used to register optional sensor properties. If * not present, some values will be defaulted. */ static constexpr uint32_t optionalControls[] = { V4L2_CID_CAMERA_SENSOR_ROTATION, }; const ControlIdMap &controls = subdev_->controls().idmap(); for (uint32_t ctrl : optionalControls) { if (!controls.count(ctrl)) LOG(CameraSensor, Debug) << "Optional V4L2 control " << utils::hex(ctrl) << " not supported"; } /* * Recommended controls are similar to optional controls, but will * become mandatory in the near future. Be loud if they're missing. */ static constexpr uint32_t recommendedControls[] = { V4L2_CID_CAMERA_ORIENTATION, }; for (uint32_t ctrl : recommendedControls) { if (!controls.count(ctrl)) { LOG(CameraSensor, Warning) << "Recommended V4L2 control " << utils::hex(ctrl) << " not supported"; err = -EINVAL; } } /* * Make sure the required selection targets are supported. * * Failures in reading any of the targets are not deemed to be fatal, * but some properties and features, like constructing a * IPACameraSensorInfo for the IPA module, won't be supported. * * \todo Make support for selection targets mandatory as soon as all * test platforms have been updated. */ Rectangle rect; int ret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP_BOUNDS, &rect); if (ret) { /* * Default the pixel array size to the largest size supported * by the sensor. The sizes_ vector is sorted in ascending * order, the largest size is thus the last element. */ pixelArraySize_ = sizes_.back(); LOG(CameraSensor, Warning) << "The PixelArraySize property has been defaulted to " << pixelArraySize_; err = -EINVAL; } else { pixelArraySize_ = rect.size(); } ret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP_DEFAULT, &activeArea_); if (ret) { activeArea_ = Rectangle(pixelArraySize_); LOG(CameraSensor, Warning) << "The PixelArrayActiveAreas property has been defaulted to " << activeArea_; err = -EINVAL; } ret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP, &rect); if (ret) { LOG(CameraSensor, Warning) << "Failed to retrieve the sensor crop rectangle"; err = -EINVAL; } if (err) { LOG(CameraSensor, Warning) << "The sensor kernel driver needs to be fixed"; LOG(CameraSensor, Warning) << "See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information"; } if (!bayerFormat_) return 0; /* * For raw sensors, make sure the sensor driver supports the controls * required by the CameraSensor class. */ static constexpr uint32_t mandatoryControls[] = { V4L2_CID_EXPOSURE, V4L2_CID_HBLANK, V4L2_CID_PIXEL_RATE, V4L2_CID_VBLANK, }; err = 0; for (uint32_t ctrl : mandatoryControls) { if (!controls.count(ctrl)) { LOG(CameraSensor, Error) << "Mandatory V4L2 control " << utils::hex(ctrl) << " not available"; err = -EINVAL; } } if (err) { LOG(CameraSensor, Error) << "The sensor kernel driver needs to be fixed"; LOG(CameraSensor, Error) << "See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information"; return err; } return 0; } /* * \brief Initialize properties that cannot be intialized by the * regular initProperties() function for VIMC */ void CameraSensor::initVimcDefaultProperties() { /* Use the largest supported size. */ pixelArraySize_ = sizes_.back(); activeArea_ = Rectangle(pixelArraySize_); } void CameraSensor::initStaticProperties() { staticProps_ = CameraSensorProperties::get(model_); if (!staticProps_) return; /* Register the properties retrieved from the sensor database. */ properties_.set(properties::UnitCellSize, staticProps_->unitCellSize); initTestPatternModes(); } void CameraSensor::initTestPatternModes() { const auto &v4l2TestPattern = controls().find(V4L2_CID_TEST_PATTERN); if (v4l2TestPattern == controls().end()) { LOG(CameraSensor, Debug) << "V4L2_CID_TEST_PATTERN is not supported"; return; } const auto &testPatternModes = staticProps_->testPatternModes; if (testPatternModes.empty()) { /* * The camera sensor supports test patterns but we don't know * how to map them so this should be fixed. */ LOG(CameraSensor, Debug) << "No static test pattern map for \'" << model() << "\'"; return; } /* * Create a map that associates the V4L2 control index to the test * pattern mode by reversing the testPatternModes map provided by the * camera sensor properties. This makes it easier to verify if the * control index is supported in the below for loop that creates the * list of supported test patterns. */ std::map<int32_t, controls::draft::TestPatternModeEnum> indexToTestPatternMode; for (const auto &it : testPatternModes) indexToTestPatternMode[it.second] = it.first; for (const ControlValue &value : v4l2TestPattern->second.values()) { const int32_t index = value.get<int32_t>(); const auto it = indexToTestPatternMode.find(index); if (it == indexToTestPatternMode.end()) { LOG(CameraSensor, Debug) << "Test pattern mode " << index << " ignored"; continue; } testPatternModes_.push_back(it->second); } } int CameraSensor::initProperties() { model_ = subdev_->model(); properties_.set(properties::Model, utils::toAscii(model_)); /* Generate a unique ID for the sensor. */ int ret = generateId(); if (ret) return ret; /* Initialize the static properties from the sensor database. */ initStaticProperties(); /* Retrieve and register properties from the kernel interface. */ const ControlInfoMap &controls = subdev_->controls(); int32_t propertyValue; const auto &orientation = controls.find(V4L2_CID_CAMERA_ORIENTATION); if (orientation != controls.end()) { int32_t v4l2Orientation = orientation->second.def().get<int32_t>(); switch (v4l2Orientation) { default: LOG(CameraSensor, Warning) << "Unsupported camera location " << v4l2Orientation << ", setting to External"; /* Fall-through */ case V4L2_CAMERA_ORIENTATION_EXTERNAL: propertyValue = properties::CameraLocationExternal; break; case V4L2_CAMERA_ORIENTATION_FRONT: propertyValue = properties::CameraLocationFront; break; case V4L2_CAMERA_ORIENTATION_BACK: propertyValue = properties::CameraLocationBack; break; } properties_.set(properties::Location, propertyValue); } else { LOG(CameraSensor, Warning) << "Failed to retrieve the camera location"; } const auto &rotationControl = controls.find(V4L2_CID_CAMERA_SENSOR_ROTATION); if (rotationControl != controls.end()) { propertyValue = rotationControl->second.def().get<int32_t>(); properties_.set(properties::Rotation, propertyValue); } properties_.set(properties::PixelArraySize, pixelArraySize_); properties_.set(properties::PixelArrayActiveAreas, { activeArea_ }); /* Color filter array pattern, register only for RAW sensors. */ if (bayerFormat_) { int32_t cfa; switch (bayerFormat_->order) { case BayerFormat::BGGR: cfa = properties::draft::BGGR; break; case BayerFormat::GBRG: cfa = properties::draft::GBRG; break; case BayerFormat::GRBG: cfa = properties::draft::GRBG; break; case BayerFormat::RGGB: cfa = properties::draft::RGGB; break; case BayerFormat::MONO: cfa = properties::draft::MONO; break; } properties_.set(properties::draft::ColorFilterArrangement, cfa); } return 0; } /** * \brief Check for and initialise any ancillary devices * * Sensors sometimes have ancillary devices such as a Lens or Flash that could * be linked to their MediaEntity by the kernel. Search for and handle any * such device. * * \todo Handle MEDIA_ENT_F_FLASH too. */ int CameraSensor::discoverAncillaryDevices() { int ret; for (MediaEntity *ancillary : entity_->ancillaryEntities()) { switch (ancillary->function()) { case MEDIA_ENT_F_LENS: focusLens_ = std::make_unique<CameraLens>(ancillary); ret = focusLens_->init(); if (ret) { LOG(CameraSensor, Error) << "CameraLens initialisation failed"; return ret; } break; default: LOG(CameraSensor, Warning) << "Unsupported ancillary entity function " << ancillary->function(); break; } } return 0; } /** * \fn CameraSensor::model() * \brief Retrieve the sensor model name * * The sensor model name is a free-formed string that uniquely identifies the * sensor model. * * \return The sensor model name */ /** * \fn CameraSensor::id() * \brief Retrieve the sensor ID * * The sensor ID is a free-form string that uniquely identifies the sensor in * the system. The ID satisfies the requirements to be used as a camera ID. * * \return The sensor ID */ /** * \fn CameraSensor::entity() * \brief Retrieve the sensor media entity * \return The sensor media entity */ /** * \fn CameraSensor::mbusCodes() * \brief Retrieve the media bus codes supported by the camera sensor * * Any Bayer formats are listed using the sensor's native Bayer order, * that is, with the effect of V4L2_CID_HFLIP and V4L2_CID_VFLIP undone * (where these controls exist). * * \return The supported media bus codes sorted in increasing order */ /** * \brief Retrieve the supported frame sizes for a media bus code * \param[in] mbusCode The media bus code for which sizes are requested * * \return The supported frame sizes for \a mbusCode sorted in increasing order */ std::vector<Size> CameraSensor::sizes(unsigned int mbusCode) const { std::vector<Size> sizes; const auto &format = formats_.find(mbusCode); if (format == formats_.end()) return sizes; const std::vector<SizeRange> &ranges = format->second; std::transform(ranges.begin(), ranges.end(), std::back_inserter(sizes), [](const SizeRange &range) { return range.max; }); std::sort(sizes.begin(), sizes.end()); return sizes; } /** * \brief Retrieve the camera sensor resolution * * The camera sensor resolution is the active pixel area size, clamped to the * maximum frame size the sensor can produce if it is smaller than the active * pixel area. * * \todo Consider if it desirable to distinguish between the maximum resolution * the sensor can produce (also including upscaled ones) and the actual pixel * array size by splitting this function in two. * * \return The camera sensor resolution in pixels */ Size CameraSensor::resolution() const { return std::min(sizes_.back(), activeArea_.size()); } /** * \fn CameraSensor::testPatternModes() * \brief Retrieve all the supported test pattern modes of the camera sensor * The test pattern mode values correspond to the controls::TestPattern control. * * \return The list of test pattern modes */ /** * \brief Set the test pattern mode for the camera sensor * \param[in] mode The test pattern mode * * The new \a mode is applied to the sensor if it differs from the active test * pattern mode. Otherwise, this function is a no-op. Setting the same test * pattern mode for every frame thus incurs no performance penalty. */ int CameraSensor::setTestPatternMode(controls::draft::TestPatternModeEnum mode) { if (testPatternMode_ == mode) return 0; if (testPatternModes_.empty()) { LOG(CameraSensor, Error) << "Camera sensor does not support test pattern modes."; return -EINVAL; } return applyTestPatternMode(mode); } int CameraSensor::applyTestPatternMode(controls::draft::TestPatternModeEnum mode) { if (testPatternModes_.empty()) return 0; auto it = std::find(testPatternModes_.begin(), testPatternModes_.end(), mode); if (it == testPatternModes_.end()) { LOG(CameraSensor, Error) << "Unsupported test pattern mode " << mode; return -EINVAL; } LOG(CameraSensor, Debug) << "Apply test pattern mode " << mode; int32_t index = staticProps_->testPatternModes.at(mode); ControlList ctrls{ controls() }; ctrls.set(V4L2_CID_TEST_PATTERN, index); int ret = setControls(&ctrls); if (ret) return ret; testPatternMode_ = mode; return 0; } /** * \brief Retrieve the best sensor format for a desired output * \param[in] mbusCodes The list of acceptable media bus codes * \param[in] size The desired size * * Media bus codes are selected from \a mbusCodes, which lists all acceptable * codes in decreasing order of preference. Media bus codes supported by the * sensor but not listed in \a mbusCodes are ignored. If none of the desired * codes is supported, it returns an error. * * \a size indicates the desired size at the output of the sensor. This function * selects the best media bus code and size supported by the sensor according * to the following criteria. * * - The desired \a size shall fit in the sensor output size to avoid the need * to up-scale. * - The sensor output size shall match the desired aspect ratio to avoid the * need to crop the field of view. * - The sensor output size shall be as small as possible to lower the required * bandwidth. * - The desired \a size shall be supported by one of the media bus code listed * in \a mbusCodes. * * When multiple media bus codes can produce the same size, the code at the * lowest position in \a mbusCodes is selected. * * The use of this function is optional, as the above criteria may not match the * needs of all pipeline handlers. Pipeline handlers may implement custom * sensor format selection when needed. * * The returned sensor output format is guaranteed to be acceptable by the * setFormat() function without any modification. * * \return The best sensor output format matching the desired media bus codes * and size on success, or an empty format otherwise. */ V4L2SubdeviceFormat CameraSensor::getFormat(const std::vector<unsigned int> &mbusCodes, const Size &size) const { unsigned int desiredArea = size.width * size.height; unsigned int bestArea = UINT_MAX; float desiredRatio = static_cast<float>(size.width) / size.height; float bestRatio = FLT_MAX; const Size *bestSize = nullptr; uint32_t bestCode = 0; for (unsigned int code : mbusCodes) { const auto formats = formats_.find(code); if (formats == formats_.end()) continue; for (const SizeRange &range : formats->second) { const Size &sz = range.max; if (sz.width < size.width || sz.height < size.height) continue; float ratio = static_cast<float>(sz.width) / sz.height; float ratioDiff = fabsf(ratio - desiredRatio); unsigned int area = sz.width * sz.height; unsigned int areaDiff = area - desiredArea; if (ratioDiff > bestRatio) continue; if (ratioDiff < bestRatio || areaDiff < bestArea) { bestRatio = ratioDiff; bestArea = areaDiff; bestSize = &sz; bestCode = code; } } } if (!bestSize) { LOG(CameraSensor, Debug) << "No supported format or size found"; return {}; } V4L2SubdeviceFormat format{ .mbus_code = bestCode, .size = *bestSize, .colorSpace = ColorSpace::Raw, }; return format; } /** * \brief Set the sensor output format * \param[in] format The desired sensor output format * * The ranges of any controls associated with the sensor are also updated. * * \return 0 on success or a negative error code otherwise */ int CameraSensor::setFormat(V4L2SubdeviceFormat *format) { int ret = subdev_->setFormat(pad_, format); if (ret) return ret; updateControlInfo(); return 0; } /** * \brief Retrieve the supported V4L2 controls and their information * * Control information is updated automatically to reflect the current sensor * configuration when the setFormat() function is called, without invalidating * any iterator on the ControlInfoMap. A manual update can also be forced by * calling the updateControlInfo() function for pipeline handlers that change * the sensor configuration wihtout using setFormat(). * * \return A map of the V4L2 controls supported by the sensor */ const ControlInfoMap &CameraSensor::controls() const { return subdev_->controls(); } /** * \brief Read V4L2 controls from the sensor * \param[in] ids The list of controls to read, specified by their ID * * This function reads the value of all controls contained in \a ids, and * returns their values as a ControlList. The control identifiers are defined by * the V4L2 specification (V4L2_CID_*). * * If any control in \a ids is not supported by the device, is disabled (i.e. * has the V4L2_CTRL_FLAG_DISABLED flag set), or if any other error occurs * during validation of the requested controls, no control is read and this * function returns an empty control list. * * \sa V4L2Device::getControls() * * \return The control values in a ControlList on success, or an empty list on * error */ ControlList CameraSensor::getControls(const std::vector<uint32_t> &ids) { return subdev_->getControls(ids); } /** * \brief Write V4L2 controls to the sensor * \param[in] ctrls The list of controls to write * * This function writes the value of all controls contained in \a ctrls, and * stores the values actually applied to the device in the corresponding \a * ctrls entry. The control identifiers are defined by the V4L2 specification * (V4L2_CID_*). * * If any control in \a ctrls is not supported by the device, is disabled (i.e. * has the V4L2_CTRL_FLAG_DISABLED flag set), is read-only, or if any other * error occurs during validation of the requested controls, no control is * written and this function returns -EINVAL. * * If an error occurs while writing the controls, the index of the first * control that couldn't be written is returned. All controls below that index * are written and their values are updated in \a ctrls, while all other * controls are not written and their values are not changed. * * \sa V4L2Device::setControls() * * \return 0 on success or an error code otherwise * \retval -EINVAL One of the control is not supported or not accessible * \retval i The index of the control that failed */ int CameraSensor::setControls(ControlList *ctrls) { return subdev_->setControls(ctrls); } /** * \fn CameraSensor::device() * \brief Retrieve the camera sensor device * \todo Remove this function by integrating DelayedControl with CameraSensor * \return The camera sensor device */ /** * \fn CameraSensor::properties() * \brief Retrieve the camera sensor properties * \return The list of camera sensor properties */ /** * \brief Assemble and return the camera sensor info * \param[out] info The camera sensor info * * This function fills \a info with information that describes the camera sensor * and its current configuration. The information combines static data (such as * the the sensor model or active pixel array size) and data specific to the * current sensor configuration (such as the line length and pixel rate). * * Sensor information is only available for raw sensors. When called for a YUV * sensor, this function returns -EINVAL. * * Pipeline handlers that do not change the sensor format using the setFormat() * function may need to call updateControlInfo() beforehand, to ensure all the * control ranges are up to date. * * \return 0 on success, a negative error code otherwise */ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const { if (!bayerFormat_) return -EINVAL; info->model = model(); /* * The active area size is a static property, while the crop * rectangle needs to be re-read as it depends on the sensor * configuration. */ info->activeAreaSize = { activeArea_.width, activeArea_.height }; /* * \todo Support for retreiving the crop rectangle is scheduled to * become mandatory. For the time being use the default value if it has * been initialized at sensor driver validation time. */ int ret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP, &info->analogCrop); if (ret) { info->analogCrop = activeArea_; LOG(CameraSensor, Warning) << "The analogue crop rectangle has been defaulted to the active area size"; } /* * IPACameraSensorInfo::analogCrop::x and IPACameraSensorInfo::analogCrop::y * are defined relatively to the active pixel area, while V4L2's * TGT_CROP target is defined in respect to the full pixel array. * * Compensate it by subtracting the active area offset. */ info->analogCrop.x -= activeArea_.x; info->analogCrop.y -= activeArea_.y; /* The bit depth and image size depend on the currently applied format. */ V4L2SubdeviceFormat format{}; ret = subdev_->getFormat(pad_, &format); if (ret) return ret; info->bitsPerPixel = format.bitsPerPixel(); info->outputSize = format.size; /* * Retrieve the pixel rate, line length and minimum/maximum frame * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE, * V4L2_CID_HBLANK and V4L2_CID_VBLANK controls is mandatory. */ ControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE, V4L2_CID_HBLANK, V4L2_CID_VBLANK }); if (ctrls.empty()) { LOG(CameraSensor, Error) << "Failed to retrieve camera info controls"; return -EINVAL; } int32_t hblank = ctrls.get(V4L2_CID_HBLANK).get<int32_t>(); info->lineLength = info->outputSize.width + hblank; info->pixelRate = ctrls.get(V4L2_CID_PIXEL_RATE).get<int64_t>(); const ControlInfo vblank = ctrls.infoMap()->at(V4L2_CID_VBLANK); info->minFrameLength = info->outputSize.height + vblank.min().get<int32_t>(); info->maxFrameLength = info->outputSize.height + vblank.max().get<int32_t>(); return 0; } /** * \fn void CameraSensor::updateControlInfo() * \brief Update the sensor's ControlInfoMap in case they have changed * \sa V4L2Device::updateControlInfo() */ void CameraSensor::updateControlInfo() { subdev_->updateControlInfo(); } /** * \fn CameraSensor::focusLens() * \brief Retrieve the focus lens controller * * \return The focus lens controller. nullptr if no focus lens controller is * connected to the sensor */ std::string CameraSensor::logPrefix() const { return "'" + entity_->name() + "'"; } int CameraSensor::generateId() { const std::string devPath = subdev_->devicePath(); /* Try to get ID from firmware description. */ id_ = sysfs::firmwareNodePath(devPath); if (!id_.empty()) return 0; /* * Virtual sensors not described in firmware * * Verify it's a platform device and construct ID from the device path * and model of sensor. */ if (devPath.find("/sys/devices/platform/", 0) == 0) { id_ = devPath.substr(strlen("/sys/devices/")) + " " + model(); return 0; } LOG(CameraSensor, Error) << "Can't generate sensor ID"; return -EINVAL; } } /* namespace libcamera */