summaryrefslogtreecommitdiff
path: root/src
AgeCommit message (Collapse)Author
2025-05-05libcamera: pipeline: vivid: Set request timestamppobrn/rebaseKieran Bingham
Provide the request SensorTimestamp as the buffer completion time. This is fake, as there is no SensorTimestamp on the VIVID pipeline as it's a virtual video device, but it provides a suitable data point. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-05libcamera: pipeline: vivid: Print diagnostic on configuration failureLaurent Pinchart
In case the setFormat() call on the video device fails to match the configuration, print both the requested and actual configurations to ease debugging. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-05libcamera: pipeline: vivid: Set camera propertiesLaurent Pinchart
Initialize the CameraData properties with Location and Model. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-05libcamera: pipeline: vivid: Handle controlsKieran Bingham
When constructing the camera, we parse the available controls on the video capture device, and map supported controls to libcamera controls, and initialise the defaults. The controls are handled during queueRequestDevice for each request and applied to the device through the capture node. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-05libcamera: pipeline: vivid: Initialise key controlsKieran Bingham
The VIVID pipeline handler retains state globally of it's controls. Ensure that when we configure this specific pipeline we set initial parameters on the device that suit our (specific) needs. This introduces how controls can be set directly on a device, however under normal circumstances controls should usually be set from libcamera controls as part of a request. These are VIVID specific only. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-05libcamera: pipeline: vivid: Queue requestsKieran Bingham
When a request is given to a pipeline handler, it must parse the request and identify what actions the pipeline handler should take to enact on hardware. In the case of the VIVID pipeline handler, we identify the buffer from the only supported stream, and queue it to the video capture device. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-05libcamera: pipeline: vivid: Buffer handling and stream controlKieran Bingham
We can now add buffer management, and connect up our bufferReady signal to a callback. Note that we provide the ability to export buffers from our capture device (data->video_) using the exportBuffers() functionality from the V4L2VideoDevice which allows a FrameBufferAllocater to obtain buffers from this device. When buffers are obtained through the exportFrameBuffers API, they are orphaned and left unassociated with the device, and must be reimported at start() time anyway. This allows the same interface to be used whether internal buffers, or external buffers are used for the stream. When a buffer completes, we call the buffer completion handler on the pipeline handler, and because we have only a single stream, we can also immediately complete the request. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-05libcamera: pipeline: vivid: Configure the deviceKieran Bingham
When the configurations have been generated and validated, they can be applied to a device. Vivid supports only a single stream, so it directly obtains the first StreamConfiguration from the CameraConfiguration. The VIVID catpure device is a V4L2Video device, so we generate a V4L2DeviceFormat to apply directly to the capture device node. Note that we convert the libcamera Format stored in cfg.pixelFormat to a V4L2PixelFormat using V4L2PixelFormat helper. This currently defaults to the single-planar formats, and should be extended to support the Multiplanar configuration from the V4L2Device. [todo Repair the link between the multiplanar configuration of the V4L2VideoDevice and the pixel format selection] Following the call to set the format using the Kernel API, if the format has been adjusted in any way by the kernel driver, then we have failed to correctly handle the validation stages, and thus the configure operation is idendified has having failed. Finally stream specific data can be directly stored and set as reflecting the state of the stream. [NOTE: the cfg.setStream() call here associates the stream to the StreamConfiguration however that should quite likely be done as part of the validation process. TBD] Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-05libcamera: pipeline: vivid: Generate and validate StreamConfigurationsKieran Bingham
Implement the support for Generating and Validating the streams the Camera can provide. Vivid is a simple case with only a single stream. Test the configurations can be generated and reported with cam -I: """ LIBCAMERA_LOG_LEVELS=Pipeline,VIVID:0 ./src/cam/cam -c 1 -I [232:02:09.633067174] [2882911] INFO IPAManager ipa_manager.cpp:136 libcamera is not installed. Adding '/home//libcamera/build-vivid/src/ipa' to the IPA search path [232:02:09.633332451] [2882911] WARN IPAManager ipa_manager.cpp:147 No IPA found in '/usr/local/lib/x86_64-linux-gnu/libcamera' [232:02:09.633373414] [2882911] INFO Camera camera_manager.cpp:283 libcamera v0.0.11+714-d1ebd889-dirty Using camera vivid 0: 1280x720-BGR888 * Pixelformat: NV21 (320x180)-(3840x2160)/(+0,+0) - 320x180 - 640x360 - 640x480 - 1280x720 - 1920x1080 - 3840x2160 * Pixelformat: NV12 (320x180)-(3840x2160)/(+0,+0) - 320x180 - 640x360 - 640x480 - 1280x720 - 1920x1080 - 3840x2160 * Pixelformat: BGRA8888 (320x180)-(3840x2160)/(+0,+0) - 320x180 - 640x360 - 640x480 - 1280x720 - 1920x1080 - 3840x2160 * Pixelformat: RGBA8888 (320x180)-(3840x2160)/(+0,+0) - 320x180 - 640x360 - 640x480 - 1280x720 - 1920x1080 - 3840x2160 """ Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-05libcamera: pipeline: vivid: Create a CameraKieran Bingham
Create a VividCameraData inheriting from the CameraData to handle camera specific data, and use it to create and register the camera with the CameraManager. This can now be tested to see that the camera becomes available to applications: """ LIBCAMERA_LOG_LEVELS=Pipeline,VIVID:0 ./src/cam/cam -l [231:44:49.325333712] [2880028] INFO IPAManager ipa_manager.cpp:136 libcamera is not installed. Adding '/home/libcamera/build-vivid/src/ipa' to the IPA search path [231:44:49.325428449] [2880028] WARN IPAManager ipa_manager.cpp:147 No IPA found in '/usr/local/lib/x86_64-linux-gnu/libcamera' [231:44:49.325446253] [2880028] INFO Camera camera_manager.cpp:283 libcamera v0.0.11+713-d175334d-dirty Available cameras: 1: vivid """ Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-05libcamera: pipeline: vivid: Match deviceKieran Bingham
Verify that we can match on our expected device(s). Use a temporary debug print to check that the pipeline finds our device: """ LIBCAMERA_LOG_LEVELS=Pipeline,VIVID:0 ./src/cam/cam -l <snipped> [230:51:10.670503423] [2872877] DEBUG VIVID vivid.cpp:81 Obtained Vivid Device """ Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-05DocumentationUseOnly: Disable compiler warningKieran Bingham
Explicitly disable the unused-parameter warning in this pipeline handler. Parameters are left unused while they are introduced incrementally, so for documentation purposes only we disable this warning so that we can compile each commit independently without breaking the flow of the development additions. This is not recommended practice within libcamera, please listen to your compiler warnings. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-05-05libcamera: pipeline: Introduce skeleton Vivid PipelineKieran Bingham
Provide all of the skeleton stubs to succesfully compile and register a new Pipeline Handler for the Vivid test device. Meson must be reconfigured to ensure that this pipeline handler is included in the selected pipelines configuration, and after building, we can test that the PipelineHandler is successfully registered by listing the cameras on the system with LIBCAMERA_LOG_LEVELS enabled: """ LIBCAMERA_LOG_LEVELS=Pipeline:0 ./build-vivid/src/cam/cam -l [230:30:03.624102821] [2867886] DEBUG Pipeline pipeline_handler.cpp:680 Registered pipeline handler "PipelineHandlerVivid" Available cameras: """ 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>
2025-04-02gstreamer: Use `Control<>` objects when setting controlsBarnabás Pőcze
`g_value_get_boolean()` returns `gboolean`, which is actually `int`. Thus // ControlValue x; auto val = g_value_get_boolean(...); x.set(val); will cause `ControlValue::set<int, ...>(const int&)` to be called, which will save the value as `ControlTypeInteger32`, not `ControlTypeBoolean`. Then, if something tries to retrieve the boolean value, it will run into an assertion failure: Assertion `type_ == details::control_type<std::remove_cv_t<T>>::value' failed. in `ControlValue::set()`. Fix this by using the appropriately typed `Control<>` object when setting the value in the `ControlList` as this ensures that the value will be converted to the actual type of the control. Bug: https://bugs.libcamera.org/show_bug.cgi?id=261 Fixes: 27cece6653e530 ("gstreamer: Generate controls from control_ids_*.yaml files") Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-02ipa: simple: Initialize ccmEnabled to falseStanislaw Gruszka
ccmEnabled variable is not initialized by default, which results in usage of CCM when the algorithm itself is not enabled and configured. The bug manifests itself as seldom reproducible corrupted video stream. Fix by initialize ccmEnabled member where it is declared. Reviewed-by: Milan Zamazal <mzamazal@redhat.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Fixes: ac3068655643 ("libcamera: software_isp: Track whether CCM is enabled") Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2025-04-01libcamera: pipeline: uvcvideo: Fix `ExposureTimeMode` control settingBarnabás Pőcze
The mapping in `UVCCameraData::processControl()` is not entirely correct because the control value is retrieved as a `bool` instead of `int32_t`. Additionally, the available modes are not taken into account. Retrieve the control value with the right type, `int32_t`, check if the requested mode is available, and if so, set the appropriate V4L2 control value selected by `addControl()` earlier. Fixes: bad8d591f8acfa ("libcamera: uvcvideo: Register ExposureTimeMode control") Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-04-01libcamera: pipeline: uvcvideo: Fix `ExposureTimeMode` control setupBarnabás Pőcze
`ControlInfo(Span<const int32_t>{...})` calls the incorrect constructor of `ControlInfo`. The intended constructor to be called is `ControlInfo(Span<const ControlValue>, ...)` however that is not called because a span of `const int32_t` is passed. Instead, the constructor `ControlInfo(const ControlValue &min, const ControlValue &max, ...)` will be called. Furthermore, since `values.back()` is used, only the last element of the array is actually set. To fix this, convert the array to contain `ControlValue` objects and use a separate variable to keep track of which element to set next. For each of `ExposureTimeMode{Auto,Manual}` save the V4L2 control value that is to be used when the libcamera control is set. Fixes: bad8d591f8acfa ("libcamera: uvcvideo: Register ExposureTimeMode control") Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
2025-04-01libcamera: camera_manager: Take camera id in `std::string_view`Barnabás Pőcze
Do not force the caller to have an `std::string` object as a simple string view is sufficient to do the lookup. 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-01libcamera: camera_manager: Simplify camera lookupBarnabás Pőcze
`std::find()` works just fine because `std::shared_ptr` has `operator==()` with the expected semantics. 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>
2025-04-01libcamera: software_isp: Reset stored exposure in black levelMilan Zamazal
Automatic black level setting in software ISP updates the determined black level value when exposure or gain change. It stores the last exposure and gain values to detect the change. BlackLevel::configure() resets the stored black level value but not the exposure and gain values. This can prevent updating the black value and cause bad image output, e.g. after suspending and resuming a camera, if exposure and gain remain unchanged. Let's store exposure and gain in IPAActiveState. Although the values are not supposed to be used outside BlackLevel class, storing them in the context has the advantage of their automatic reset together with the other context contents and having them in `blc' struct indicates their relationship to the black value computation. Bug: https://bugs.libcamera.org/show_bug.cgi?id=259 Signed-off-by: Milan Zamazal <mzamazal@redhat.com> Tested-by: Robert Mader <robert.mader@collabora.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-03-28ipa: simple: Report exposure in metadataMilan Zamazal
Report exposure and gain in metadata. This is more complicated than it could be expected because the exposure value should be in microseconds but it's handled using V4L2_CID_EXPOSURE control, which doesn't specify the unit, see https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/control.html. So the unit conversion is done in the way rkisp1 IPA uses. This requires getting and passing IPACameraSensorInfo around. To avoid naming confusion and to improve consistency with rkisp1 IPA, sensorCtrlInfoMap parameter is renamed to sensorControls. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Milan Zamazal <mzamazal@redhat.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2025-03-28ipa: simple: Report contrast in metadataMilan Zamazal
Provide the requested contrast value, if any, in the metadata to add to the completed requests. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Milan Zamazal <mzamazal@redhat.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>