summaryrefslogtreecommitdiff
path: root/src
AgeCommit message (Collapse)Author
4 dayslibipa: awb: Make result of gainsFromColourTemp optionalStefan Klug
In the grey world AWB case, if no colour gains are contained in the tuning file, the colour gains get reset to 1 when the colour temperature is set manually. This is unexpected and undesirable. Allow the gainsFromColourTemp() function to return a std::nullopt to handle that case. While at it, remove an unnecessary import from rkisp1/algorithms/awb.h. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
4 daysipa: rkisp1: Implement manual ColourCorrectionMatrix controlStefan Klug
Add a manual ColourCorrectionMatrix control. This was already discussed while implementing manual colour temperature but was never implemented. The control allows to manually specify the CCM when AwbEnable is false. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
4 daysipa: rkisp1: ccm/lsc: Fix CCM/LSC based on manual color temperatureStefan Klug
In RkISP1Awb::process(), the color temperature in the active state is updated every time new statistics are available. The CCM/LSC algorithms use that value in prepare() to update the CCM/LSC. This is not correct if the color temperature was specified manually and leads to visible flicker even when AwbEnable is set to false. To fix that, track the auto and manual color temperature separately in active state. In Awb::prepare() the current frame context is updated with the corresponding value from active state. Change the algorithms to fetch the color temperature from the frame context instead of the active state in prepare(). Fixes: 02308809548d ("ipa: rkisp1: awb: Implement ColourTemperature control") Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
4 daysipa: rkisp1: algorithms: awb: Fix wrong colour temperature reportingStefan Klug
In commit b60bd37b1a49 ("ipa: rkisp1: Move calculation of RGB means into own function") the output of the current measured colour temperature as metadata was incorrectly added. Remove it. Fixes: b60bd37b1a49 ("ipa: rkisp1: Move calculation of RGB means into own function") Signed-off-by: Stefan Klug <stefan.klug@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>
4 daysipa: rkisp1: Refactor automatic/manual structure in IPAActiveStateStefan Klug
Swap gains and automatic/manual in the IPAActiveState structure. This is in preparation to adding another member, which is easier in the new structure. The patch contains no functional changes. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
4 dayslibcamera: vector: Extend matrix multiplication operator to heterogenous typesLaurent Pinchart
It is useful to multiply matrices and vectors of heterogeneous types, for instance float and double. Extend the multiplication operator to support this, avoiding the need to convert one of the operations. The type of the returned vector is selected automatically to avoid loosing precision. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
4 dayslibcamera: matrix: Extend multiplication operator to heterogenous typesLaurent Pinchart
It is useful to multiply matrices of heterogneous types, for instance float and double. Extend the multiplication operator to support this, avoiding the need to convert one of the matrices. The type of the returned matrix is selected automatically to avoid loosing precision. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
4 dayslibcamera: matrix: Add inverse() functionStefan Klug
For calculations in upcoming algorithm patches, the inverse of a matrix is required. Add an implementation of the inverse() function for square matrices. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
4 dayslibcamera: vector: Add a Span based constructorStefan Klug
When one wants to create a Vector from existing data, currently the only way is via std::array. Add a Span based constructor to allow creation from std::vectors and alike. While at it, replace the manual loop with std::copy. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
4 dayslibcamera: matrix: Add a Span based constructorStefan Klug
When one wants to create a Matrix from existing data, currently the only way is via std::array. Add a Span based constructor to allow creation from vectors and alike. Signed-off-by: Stefan Klug <stefan.klug@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>
4 daysipa: rkisp1: awb: Ignore empty AWB statisticsStefan Klug
When the AWB engine doesn't find a valid pixel because all pixels lie outside the configured colour range it returns an AWB measurement value of 255, 255, 255. This leaves the regulation in an unrecoverable state noticeable by a completely green image. Fix that by skipping the AWB calculation in case there were no valid pixels. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
5 daysgstreamer: Add GstVideoMeta supportHou Qi
GStreamer video-info calculated stride and offset may differ from those used by the camera. For stride and offset mismatch, this patch adds video meta to buffer if downstream supports VideoMeta through allocation query. Otherwise, create a internal VideoPool using the caps, and copy video frame to this system memory. Signed-off-by: Hou Qi <qi.hou@nxp.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Tested-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
8 daysapps: cam: sdl_sink: Support more single-plane formatsBarnabás Pőcze
With the newly introduced `SDLTexture1Plane` it is easy to handle any single-plane format that has an SDL equivalent. So use it for more YUV and RGB formats. The mapping of RGB formats is not entirely straightforward because `SDL_PIXELFORMAT_ZZZ...888...` defines a format where the order of the components is endian dependent, while libcamera's `ZZZ...888...` formats are derived from the matching DRM formats, and the RGB formats in question are defined to be little-endian there. So the endian-independent `SDL_PIXELFORMAT_{ZZZ24,ZZZZ32}` are used. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
8 daysapps: cam: sdl_texture: Add `SDLTexture1Plane`Barnabás Pőcze
`SDLTextureYUYV` uses `SDL_PIXELFORMAT_YUY2`, which is a single plane format. To support other single plane formats, replace `SDLTextureYUYV` with `SDLTexture1Plane` that can be instantiated with an arbitrary SDL pixel format and that uses `SDL_UpdateTexture()` to update the texture using exactly a single plane. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
8 daysapps: cam: sdl_texture: Drop `&rect_` from `SDL_Update{NV,}Texture()` callBarnabás Pőcze
If the entire texture is to be updated, there is no need to specify the target area explicitly. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
8 daysapps: cam: sdl_texture: Take list of buffers in spanBarnabás Pőcze
A non-owning span is sufficient, so use that instead of a vector. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
10 dayslc-compliance: Move camera setup to CameraHolder classNícolas F. R. A. Prado
Different base classes can be used for different setups on tests, but all of them will need to setup the camera for the test. To reuse that code, move it to a separate CameraHolder class that is inherited by test classes. Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
11 daysipa: rkisp1: awb: Declare ControlInfo in AWBPaul Elder
The ControlInfo information for AwbEnable and ColourGains are declared and exposed in the top-level IPA. These should instead be exposed by the AWB part of the IPA, as it doesn't make sense to support these controls when AWB is disabled, for example. Move the declaration of these controls out of the top-level IPA and into AWB. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 daysipa: Move IPA installations to a subdirKieran Bingham
IPAs are expected to live within a directory that is searched by the IPAManager. If other non-IPA so files are installed in the same location, then the user may be presented with an error message reporting that the module could not be parsed. Move IPA modules to an ipa specific subdirectory to ensure we only parse .so files that are expected to be IPA modules at load time. Bug: https://bugs.libcamera.org/show_bug.cgi?id=268 Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
12 dayspy: Set `PYTHONPATH` in devenvBarnabás Pőcze
If the python bindings are built, then set the `PYTHONPATH` environmental variable in the meson devenv accordingly to make it easy to use. $ meson devenv -C build [libcamera] $ echo $PYTHONPATH /libcamera/build/src/py [libcamera] $ python Python 3.13.3 (main, Apr 9 2025, 07:44:25) [GCC 14.2.1 20250207] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import libcamera >>> cm = libcamera.CameraManager.singleton() [...] [129:52:33.293860558] [4133380] INFO Camera camera_manager.cpp:326 libcamera v0.5.0+169-7dbe74b5-dirty (2025-05-01) [...] Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-05-09libcamera: v4l2_videodevice: Log buffer count on allocation errorSven Püschel
Log the actual and requested buffers count in case of a V4L2 buffers allocation error, when the requested buffers count could not be allocated. Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-05-08apps: qcam: Push the viewfinder role to vectorKieran Bingham
In commit ee2b011b65c6 ("apps: cam: Try raw role if default viewfinder role fails"), the viewfinder role is specified as the default if no role is yet chosen. This was unfortunately added by directly accessing the vector rather than extending the size when the vector is empty. Fix the code to push the default viewfinder role on to the back of the vector, increasing the size appropriately. Fixes: ee2b011b65c6 ("apps: cam: Try raw role if default viewfinder role fails") Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-30ipa: rpi: awb: Remove "fast" parameterBarnabás Pőcze
The "fast" parameter has not been used since it first appeared in the source code. And not only is it not used, but its retrieval from the configuration since c1597f989654 ("ipa: raspberrypi: Use YamlParser to replace dependency on boost") has been incorrect. So remove it. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com>
2025-04-29ipa: rpi: common: Avoid warnings when AeEnable control is usedDavid Plowman
The AeEnable control is now just a wrapper that is converted to ExposureTimeMode and AnalogueGainMode controls instead. Therefore, it should simply be ignored when we encounter it, without the need for any warnings. Signed-off-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-29libcamera: stream: Add color space to configuration string representationLaurent Pinchart
Extend the string representation of StreamConfiguration, as returned by the toString() and operator<<() functions, with color space information. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2025-04-29libcamera: pipeline: rkisp1: Convert to use MediaPipelineKieran Bingham
Use the new MediaPipeline to manage and identify all sensors connected to complex pipelines that can connect to the CSI2 receiver before the ISP. This can include chained multiplexors that supply multiple cameras, so make use of the MediaDevice::locateEntities to search for all cameras and construct a pipeline for each. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Acked-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-04-29libcamera: internal: Add MediaPipeline helperKieran Bingham
Provide a MediaPipeline class to help identifing and managing pipelines across a MediaDevice graph. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-04-29libcamera: media_device: Add helper to return matching entitiesKieran Bingham
Provide a helper on the MediaDevice to return a list of all available entities which match a given function in the graph. As a drive by, also fix a whitespace error in the documentation of MediaDevice::setupLink. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>
2025-04-29apps: cam: Try raw role if default viewfinder role failsPaul Elder
cam currently defaults to the viewfinder role when no role is specified. This means that on platforms that only support the raw role (such as a raw sensor with no softISP on a simple pipeline platform), generateConfiguration() would return nullptr and cam would bail out. At least this is what is supposed to happen based on the little documentation that we have written regarding generateConfiguration(), specifically in the application writer's guide, which is probably the most influential piece of documentation: The ``Camera::generateConfiguration()`` function accepts a list of desired roles and generates a ``CameraConfiguration`` with the best stream parameters configuration for each of the requested roles. If the camera can handle the requested roles, it returns an initialized ``CameraConfiguration`` and a null pointer if it can't. Currently the simple pipeline handler will return a raw configuration anyway (if it only supports raw) even if a non-raw role was requested. Thus cam receives a raw configuration instead of a nullptr when no role is specified and viewfinder is requested. However, in the near future, support for raw streams with softISP on the simple pipeline handler will be merged. This will notably change the behavior of the simple pipeline handler to return nullptr if a non-raw role was requested on a platform that only supports raw. This is proper behavior according to documentation, but changes cam's behavior as it used to capture fine with no parameters but will no longer be able to. Technically this is an issue with the roles API, as we are mixing roles in the sense of "configuration hints" (eg. viewfinder vs recording vs still capture) with roles in the sense of "platform capabilities" (raw vs everything else). In the long term the proper solution is to rework the roles API. In the meantime, fix cam so that it will try the raw role if the default viewfinder role returns no configuration. cam is an app that is capable of using the raw stream, so this is appropriate behavior. If roles are specified, then do not retry, as in this situation the user knows what streams they can use and what they want. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
2025-04-23gstreamer: Fixate colorimetry field during caps negotiationHou Qi
When libcamerasrc is negotiating with downstream element, it first extracts colorimetry field from downstream supported caps, then set this colorimetry to its stream configuration and propagates the colorimetry downstream. Currently libamerasrc only considers the case there is one colorimetry in colorimetry field of downstream caps. But the issue is that downstream caps may report a list of supported colorimetry, which causes libcamerasrc to set unknown colorimetry to stream configuration and negotiate fail with downstream element. In order to fix the issue, need to fixate colorimetry field before getting colorimetry string. Signed-off-by: Hou Qi <qi.hou@nxp.com> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-22libcamera: ipa_module: Avoid unnecessary copy when getting signatureBarnabás Pőcze
The `signature()` getter can just return a reference to the private vector member variable, and let the caller make a copy if needed. Since the return type is const qualified, this was likely the original intention. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2025-04-22pipeline: rkisp1: Fix vblank delayPaul Elder
The vblank delay for delayed controls was incorrectly hardcoded to 1. Get it from the camera sensor properties instead. Fixes: f72c76eb6e06 ("rkisp1: Honor the FrameDurationLimits control") Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-22Revert "libcamera: rkisp1: Eliminate hard-coded resizer limits"Quentin Schulz
This reverts commit e85c7ddd38ce8456ab01c2a73baf9e788f6a462e. Linux kernel predating 6.4 (specifically commit 7cfb35d3a800 ("media: rkisp1: Implement ENUM_FRAMESIZES") do not have the ioctl in rkisp1 driver required to dynamically query the resizer limits. Because of that, maxResolution and minResolution are both {0, 0} (default value for Size objects) which means filterSensorResolution() will create an entry for the sensor in sensorSizesMap_ but because the sensor resolution cannot fit inside the min and max resolution of the rkisp1, no size is put into this entry in sensorSizesMap_. On the next call to filterSensorResolution(), sensorSizesMap_.find(sensor) will return the entry but when attempting to call back() on iter->second, it'll trigger an assert because the size array is empty. Linux kernel 6.1 is supported until December 2027, so it seems premature to get rid of those hard-coded resizer limits before this happens. Let's restore the hard-coded resizer limits as fallbacks, actual limits are still queried from the driver on recent enough kernels. Fixes: 761545407c76 ("pipeline: rkisp1: Filter out sensor sizes not supported by the pipeline") Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-21apps: cam: capture_script: Simplify bool array parsingBarnabás Pőcze
`std::vector<bool>` is a specialization that implements a dynamic bit vector, therefore it is not suitable to provide storage for an array of `bool`. Hence a statically sized array is used when parsing an array of boolean values. Instead, use the array overload of `std::make_unique` since the size is known beforehand. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-04-21libcamera: pipeline: imx8-isi: Remove unused variableBarnabás Pőcze
The `mbusCodes` variable in `ISICameraConfiguration::validateRaw()` has been unused since 87fed432533a ("libcamera: imx8-isi: Break out RAW format selection"), so remove it. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-21libcamera: pipeline: virtual: Fix typo in log messageBarnabás Pőcze
pass -> parse Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-15libcamera: software_isp: Fix CCM multiplicationMilan Zamazal
A colour correction matrix (CCM) is applied like this to an RGB pixel vector P: CCM * P White balance must be applied before CCM. If CCM is used, software ISP makes a combined matrix by multiplying the CCM by a white balance gains CCM-like matrix (WBG). The multiplication should be as follows to do it in the correct order: CCM * (WBG * P) = (CCM * WBG) * P The multiplication order in Lut software ISP algorithm is reversed, resulting in colour casts. Let's fix the order. Signed-off-by: Milan Zamazal <mzamazal@redhat.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-15libcamera: pipeline: uvcvideo: Expose `Gamma` controlBarnabás Pőcze
Commit 294ead848c3fa2 ("libcamera: Add gamma control id") introduced the "Gamma" control, so expose it for UVC cameras as well using the `V4L2_CID_GAMMA` control. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Tested-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-15libcamera: request: Avoid double map lookupBarnabás Pőcze
Use `try_emplace()` that more or less combines `find()` and `operator[]` in one function. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-15apps: lc-compliance: Add multi-stream testsBarnabás Pőcze
Rename the `SingleStream` test to `SimpleCapture`, and extend it to support using multiple roles. And instantiate another test suite from the `SimpleCapture` test that tests multiple streams in one capture session. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-04-15apps: lc-compliance: Support multiple streams in helpersBarnabás Pőcze
Prepare to add a test suite for capture operations with multiple streams. Modify the Capture helper class to support multiple roles and streams in the configure() and capture() operations. The buffer count of each stream is asserted to be the same. Multi-stream support will be added in next patches. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-04-10libcamera: software_isp: Add a clarification comment to AWBMilan Zamazal
The computed AWB gains are applied when constructing LUT tables rather than in awb.cpp itself. This can look confusing when reading awb.cpp, let's add a clarifying comment. Signed-off-by: Milan Zamazal <mzamazal@redhat.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>
2025-04-03libipa: histogram: Fix interQuantileMean() for small rangesStefan Klug
The interQuantileMean() is supposed to return a weighted mean value between two quantiles. This works for fine histograms, but fails for coarse histograms and small quantile ranges because the weight is always taken from the lower border of the bin. Fix that by rewriting the algorithm to calculate a lower and upper bound for every (partial) bin that goes into the mean calculation and weight the bins by the middle of these bounds. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-03libipa: histogram: Fix quantile() calculation for fractional resultsStefan Klug
The calculation of the frac variable is based solely on integers and therefore results in the fractional part being either 0 or 1. In the original code from RaspberryPi this is mitigated by casting the nominator to a double. This works for most cases, but fails when q is very small because of the quantization introduced by item being an integer. Fix both issues by doing the full calculation in double and remove the should_fail tag. Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-04-03pipeline: simple: Reset delayedCtrls at startStanislaw Gruszka
Similar like in other pipelines (IPU3, rpi) avoid using stale values of DelayedControls class when the same camera is started second time. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com> Co-developed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-03pipeline: simple: Create DelayedControls instance once onlyLaurent Pinchart
The DelayedControls instance for the camera sensor is created in SimplePipelineHandler::configure(). Constant deletion and reconstruction of a new object is unnecessary, as the control delays are an intrinsic property of the sensor and are known at initialization time. Move the DelayedControls creation to the SimpleCameraData class constructor. Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com> # v6 Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-03pipeline: simple: Enable frame start eventsStanislaw Gruszka
The simple pipeline handler uses frame start events to apply sensor controls through the DelayedControls class. The setSensorControls() function applies the controls directly, which would result in controls being applied twice, if it wasn't for the fact that the pipeline handler forgot to enable the frame start events in the first place. Those two issues cancel each other, but cause controls to always be applied directly. Fix the issue by only applying controls directly in setSensorControls() if no frame start event emitter is available, and by enabling the frame start events in startDevice() otherwise. Disable them in stopDevice() for symmetry. Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com> # v6 Co-developed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Co-developed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-03pipeline: simple: Connect/disconnect frameStart signal at start/stop timeStanislaw Gruszka
The frameStart signal from the frame start emitter is connected in the configure() function, and is never disconnected. This means that each time the camera is configured a new connection is made, causing the DelayedControls::applyControls() to be called multiple times. Fix it by connecting and disconnecting the signal when starting and stopping the camera. Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com> # v6 Co-developed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Co-developed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-03libcamera: v4l2_device: add frame start event helpersStanislaw Gruszka
Add helper to check if frame start event are supported by subdevice. Since kernel does not have interface to query supported events use subscribe interface. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> # v3 Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> # v5 Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-02pipeline: rpi: Fix potential empty optional readBarnabás Pőcze
If `!target`, then `*target` is undefined behaviour, so check if the optional is empty when printing the error message. Simplify the check as well. Fixes: 6c71ee1f153051 ("pipeline: raspberrypi: Introduce PipelineHandlerBase class") Fixes: 841ef2b4bb08ba ("pipeline: rpi: Add support for Raspberry Pi 5") Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.com>