summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2020-10-07android: camera_stream: Retrieve Stream and ConfigurationJacopo Mondi
It's a common pattern to access the libcamera::Stream and libcamera::StreamConfiguration using the CameraStream instance's index. Add two methods to the CameraStream to shorten access to the two fields. This allows removing the index() method from the class interface. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2020-10-07android: camera_device: Move processing to CameraStreamJacopo Mondi
Move the JPEG processing procedure to the individual CameraStream by augmenting the class with a CameraStream::process() method. This allows removing the CameraStream::encoder() method. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2020-10-07android: camera_stream: Construct with Android streamJacopo Mondi
Pass the android camera3_stream_t, and a libcamera::StreamConfiguration to identify the source and destination parameters of this stream. Pass a CameraDevice pointer to the CameraStream constructor to allow retrieval of the StreamConfiguration associated with the CameraStream. Also change the format on which the CameraDevice performs checks to decide if post-processing is required, as the libcamera facing format is not meaningful anymore, but the Android requested format should be used instead. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2020-10-07android: camera_stream: Delegate Encoder constructionJacopo Mondi
Delegate the construction of the encoder to the CameraStream class for streams that need post-processing. Reviewed-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: Jacopo Mondi <jacopo@jmondi.org>
2020-10-07android: camera_stream: Add CameraStream::TypeJacopo Mondi
Define the CameraStream::Type enumeration and assign it to each CameraStream instance at construction time. The CameraStream type will be used to decide if memory needs to be allocated on its behalf or if the stream is backed by memory externally allocated by the Android framework. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Hirokazu Honda <hiroh@chromium.org> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2020-10-07android: camera_stream: Break out CameraStreamJacopo Mondi
Break CameraStream out of the CameraDevice class. No functional changes, only the code is moved. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2020-10-07ipa: raspberrypi: fix access to uninitialized variablesTomi Valkeinen
Set span_r and span_b to -1 so that when they are passed to Pwl::Eval() they won't cause access to uninitialized memory. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@iki.fi> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-10-07ipa: raspberrypi: fix bin_x calculationTomi Valkeinen
I presume this code is supposed to set bin_x and bin_y, and not bin_y two times. This caused use of uninitialized variable later when bin_x was used. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@iki.fi> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-10-07android: jpeg: exif: Sanitize ASCII strings with utils::toAscii()Umang Jain
Use the newly introduced utils::toAscii() utility to remove all non-ASCII characters for EXIF_FORMAT_ASCII strings. Signed-off-by: Umang Jain <email@uajain.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-10-07libcamera: PipelineHandler: Move printing pipeline names to CameraManagerPaul Elder
Since pipeline registration is done with declaring static factory objects, there is a risk that pipeline factories will be constructed before libcamera facilities are ready. For example, logging in the constructor of a pipeline handler factory may cause a segfault if threading isn't ready yet. Avoid this issue by moving printing the registration of the pipeline handler to the camera manager. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2020-10-07libcamera: ProcessManager: make ProcessManager lifetime explicitly managedPaul Elder
If any Process instances are destroyed after the ProcessManager is destroyed, then a segfault will occur. Fix this by making the lifetime of the ProcessManager explicit, and make the CameraManager construct and deconstruct (automatically, via a member variable) the ProcessManager. Update the tests accordingly. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2020-10-07Documentation: coding-style: Document global variable guidelinesPaul Elder
Document the issue related to global variable dependencies and how to avoid them. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-10-07libcamera: file_descriptor: Remove spurious 'is'Jacopo Mondi
Remove a spurious 'is' is a comment block. Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Umang Jain <email@uajain.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2020-10-07pipeline: ipa: raspberrypi: Switch to use C++17 features where possibleNaushir Patuck
With the recent change to use C++17, the following code changes can be made: - Use C++17 [[fallthough]] attribute instead of /* Fall through */. - Swap boost::any to std::any. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-10-04qcam: viewfinder_gl: Add shader to render packed YUV formatsLaurent Pinchart
The shader supports all 4 packed 8-bit YUV variants. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-10-04qcam: viewfinder_gl: Merge the semi-planar UV and VU shadersLaurent Pinchart
Use macros to select the U and V pattern, to avoid code duplication between the two semi-planar shaders. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-10-04qcam: viewfinder_gl: Support #define in shadersLaurent Pinchart
Prepare the infrastructure to support defining preprocessor macros in shaders: - Rename the fragmentShaderSrc_ member to fragmentShaderFile_ to reflect better that it contains a file name, not shader source code - Add a new fragmentShaderDefines_ member to store preprocessor macros - Prepend the macros to the shader source before compiling it Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-10-04qcam: viewfinder_gl: Rename shader filesLaurent Pinchart
Rename shader files to prepare for packed YUYV support: - The NV prefix isn't a good match for packed (or for 3-planar) formats, replace it with a YUV prefix - Use .frag and .vert extensions to differentiate between fragment and vertex shaders Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-10-04qcam: viewfinder_gl: Hardcode the vertex shader file nameLaurent Pinchart
The GL renderer uses the same vertex shader for all formats. Hardcode the file name instead of storing it in a member variable. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-10-04qcam: viewfinder_gl: Don't store texture IDs in class membersLaurent Pinchart
The texture IDs can easily and cheaply be retrieved from the textures, there's no need to store them in class members. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-10-04qcam: Remove unneeded './' file prefix in *.qrcLaurent Pinchart
There's no need to prefix files in the local directory with './'. Drop it. While at it, add indentation to make the *.qrc files more readable. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-10-02pipeline: raspberrypi: Sensor flips should be applied unconditionallyNaushir Patuck
The code in pipeline_handler::start() that applies the flips were in a block that was conditional on the RPi::IPA_CONFIG_STAGGERED_WRITE return result. This should be applied unconditionally. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-10-02qcam: dng_writer: Record camera modelNiklas Söderlund
Record the model property of the camera if available. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Umang Jain <email@uajain.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-10-02cam: Print user-friendly camera namesNiklas Söderlund
Instead of only printing the camera ID which is not intended for humans to read and parse create a more user-friendly string when printing camera names. The ID is still printed as it is one option used to select camera using the --camera option. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Umang Jain <email@uajain.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-10-02libcamera: pipeline: uvcvideo: Set sensor model propertyNiklas Söderlund
Set the sensor model property from the model reported in the media graph. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-10-02libcamera: pipeline: uvcvideo: Initialize CameraData from MediaDeviceNiklas Söderlund
The UVCCameraData::init() is the only consumer of the default entry in the media graph, move the lookup of it into the init() function and pass it the MediaDevice. This is done in preparation to extend the CameraData initialization to consume more information from the MediaDevice. 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>
2020-10-02libcamera: camera_sensor: Set sensor model propertyNiklas Söderlund
Set the sensor model property. 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-10-02libcamera: utils: Add method to remove non-ASCII charactersNiklas Söderlund
Add method that removes non-ASCII characters from a string. 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: Umang Jain <email@uajain.com>
2020-10-02libcamera: properties: Add model propertyNiklas Söderlund
The model name must to the extent possible describe the sensor. For most devices this is the model name of the sensor. While for some devices the sensor model is unavailable as the sensor or the entire camera is part of a larger unit and exposed as a black-box to the system. In such cases the model name of the smallest component closest to the sensor must be used. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-10-02utils: hooks: pre-push: Accept Acked-by in addition to Reviewed-byLaurent Pinchart
Allow pushing commits that have no Reviewed-by tag but have at least one Acked-by tag. 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>
2020-10-02src: android: exif: Set the class byte orderingKieran Bingham
The exif object sets the byte ordering on construction, and then during later calls re-states the byte ordering when setting values. It could be argued that this ordering should already be known to the exif library and is redundant, but even so we must provide it. Ensure we are consistent in always using the same byte ordering by setting a private class member to re-use a single value. Reviewed-by: Umang Jain <email@uajain.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-10-01libcamera: pipeline: rkisp1: Add support for XRGB8888Niklas Söderlund
The self path supports XRGB8888, list it as a supported format. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-10-01libcamera: Add support for XRGB8888 and XBGR8888Niklas Söderlund
Add support for XRGB8888 and XBGR8888 formats. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-10-01libcamera: pipeline: rkisp1: Add support for R8Niklas Söderlund
Both the main and self path support R8, list it as a supported format. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-10-01libcamera: pipeline: rkisp1: Add support for RGB656Niklas Söderlund
The self path supports RGB565, list it as a supported format. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-10-01libcamera: pipeline: rkisp1: Fix media bus propagation for NV{12,21}Niklas Söderlund
The upstream driver has changed how the link formats are validated when starting to stream [1]. This revealed that libcamera did not adjust the media bus format from the link between {main,self} resizer source pad and the capture video device as expected by the driver. The media bus code YUYV8_2X8 was hardcoded to MEDIA_BUS_FMT_YUYV8_2X8 for all pixel formats while it must be adjusted to YUYV8_1_5X8 for NV12 and NV21, fix this. 1. 6803a9e0e1e43e9e ("media: staging: rkisp1: cap: simplify link validation by comparing media bus code") Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-10-01libcamera: pipeline: rkisp1: Remove support for YVYU and VYUYNiklas Söderlund
The upstream driver has dropped support for YVYU and VYUY [1], remove support from the pipeline handler. 1. 3acb3e06baf64e28 ("media: staging: rkisp1: cap: remove unsupported formats") Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-09-30libcamera: span: Use default copy assignemnt operatorLaurent Pinchart
The custom implementation of the copy assignment operator is identical to the one the compiler would generate. Replace it by the default. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-09-30libcamera: pipeline: rkisp1: Use the media link to track if a path is enabledNiklas Söderlund
Instead of manually tracking if a path is enable or not use the media graph link status. There is no functional change. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-09-30libcamera: pipeline: rkisp1: Move path link handling to RkISP1PathNiklas Söderlund
Move the path link handling to RkISP1Path, there is no functional change. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-09-30libcamera: pipeline: rkisp1: Move start and stop of path to RkISP1PathNiklas Söderlund
Move the start and stop of a path to RkISP1Path. This allows the importing of buffers to be moved closer the path start/stop simplifying the code. Also by adding a simple running tracker the error logic in PipelineHandlerRkISP1 can be simplified as stop() can always be called. This also removes all external users of RkISP1Path::video_ so it can be made private. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-09-30libcamera: pipeline: rkisp1: Add wrappers for accessing the path video deviceNiklas Söderlund
As a step to be able to make RkISP1Path::video_ private add simple wrappers for buffer handling. There is no functional change. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-09-30libcamera: pipeline: rkisp1: Move path configuration generation and ↵Niklas Söderlund
validation to RkISP1Path Move the path configuration generation and validation to RkISP1Path. This is done to increase code reuse and to encapsulate the main and self path differences inside the RkISP1Path class. There is no functional change. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-09-30libcamera: pipeline: rkisp1: Move path configuration to RkISP1PathNiklas Söderlund
Move the path configuration to RkISP1Path to increase code reuse and make the V4L2 subdevice resizer private to the path. There is no functional change. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-09-30libcamera: pipeline: rkisp1: Breakout basic path handling to own classNiklas Söderlund
The self and main paths are very similar and the introduction of support for two simultaneous streams have made it clear their handling could be abstracted in a separate class. This is the first step to create such a class by breaking out the initialization and storage of the video and subdevices. There is no functional change in this patch. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2020-09-30libcamera: stream: Rename StillCaptureRaw to RawNiklas Söderlund
With the buffer copy removed from all pipelines for raw capture rename StillCaptureRaw to Raw to better describe the role. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2020-09-30Documentation: guides: pipeline-handler: Update clamp() namespaceUmang Jain
Update the sample code using utils::clamp() to std::clamp(). Fixes: f2734ff3ab09 ("libcamera: Replace utils::clamp() with std::clamp()") Signed-off-by: Umang Jain <email@uajain.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2020-09-29libcamera: ipu3: Adjust comment on ImgU configurationJacopo Mondi
Be more precise in commenting why the ImgU shall not be configured if only the RAW stream is requested. As an example, if the ImgU gets unecessary configured: cam -srole=viewfinder -c2 -C -> WORKS cam -srole=stillraw -c2 -C -> WORKS cam -srole=viewfinder -c2 -C -> Failed to queue buffer 0: Invalid argument Since commit ("libcamera: ipu3: Fix RAW+YUV capture") the ImgU configuration procedure also correctly implements the assumption that at least one of the YUV output is being operated. If that's not the case, as in the RAW-only capture use case, the code tries to access a non-existing configuration. One more reason to exit early if no YUV stream is requested. 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-09-29libcamera: ipu3: Remove dead code checkJacopo Mondi
Since the re-implementation of the IPU3 pipeline handler configuration procedure, the main output is always assigned in case any YUV stream is requested. Remove a dead code block that checks for the main output to be valid. 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-09-29libcamera: ipu3: Fix RAW+YUV captureJacopo Mondi
When requesting one RAW stream and one YUV stream the StreamConfiguration assigned to the RAW stream is the first one added to the CameraConfiguration, while the YUV stream gets assigned to the main output. At configure() time the viewfinder output needs to be configured with the same format as the main output, but since the introduction of RAW capture support, the pipeline has not been updated and still assumes the main output configuration is the first one in the CameraConfiguration. This causes the viewfinder to be configured with the same format as the raw stream, breaking capture operations. Before this commit the following command fails and the ImgU does not produce frames: cam -srole=stillraw -srole=viewfinder -c2 -C 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>