summaryrefslogtreecommitdiff
path: root/src
AgeCommit message (Collapse)Author
2019-05-23libcamera: pipeline: Move camera data classes to the top level scopeLaurent Pinchart
Move the pipeline handler camera data classes, defined in the scope of the respective pipeline handler class, to the top level of the libcamera namespace. This prepares for the introduction of other classes that will make use of them in the IPU3 and RkISP1 pipeline handlers. The UVC and VIMC pipeline handlers are updated as well for consistency. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-05-23libcamera: camera: Return a pointer from generateConfiguration()Laurent Pinchart
To prepare for specialising the CameraConfiguration class in pipeline handlers, return a pointer to a camera configuration instead of a reference from Camera::generateConfiguration(). The camera configuration always needs to be allocated from the pipeline handler, and its ownership is passed to the application. For symmetry, change Camera::configure() to take a CameraConfiguration pointer instead of a reference. This aligns with our coding practice of passing parameters that are modified by the callee by pointer. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-05-23libcamera: Refactor the camera configuration storage and APILaurent Pinchart
Refactor the CameraConfiguration structure to not rely on Stream instances. This is a step towards making the camera configuration object more powerful with configuration validation using "try" semantics. The CameraConfiguration now exposes a simple vector-like API to access the contained stream configurations. Both operator[]() and at() are provided to access elements. The isEmpty() method is renamed to empty() and the methods reordered to match the std::vector class. As applications need access to the Stream instances associated with the configuration entries in order to associate buffers with streams when creating requests, expose the stream selected by the pipeline handler through a new StreamConfiguration::stream(). Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-05-23libcamera: Use stream roles directly instead of StreamUsageLaurent Pinchart
In order to prepare for an API overhall of the camera configuration generation, remove the StreamUsage class and replace its uses by stream roles. The size hints can't be specified anymore, and will be replaced with an API on the StreamConfiguration to negotiate configuration parameters with cameras. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-05-23libcamera: camera: Rename configureStreams() and streamConfiguration()Laurent Pinchart
Rename the configureStreams() and streamConfiguration() methods to configure() and generateConfiguration() respectively in order to clarify the API. Both methods deal with CameraConfiguration objects, and are thus not limited to streams, even if a CameraConfiguration currently contains streams only. While at it, remove the qcam MainWindow::configureStreams() method that is declared but never defined or used. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-05-21libcamera: ipa_module: add IPA shared library modulePaul Elder
Implement a class to wrap around an IPA module shared object. For now, just load a struct IPAModuleInfo with symbol name ipaModuleInfo from an IPA module .so shared object. Also provide a public header file including the struct IPAModuleInfo, structured such that both C and C++ IPA modules are supported. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-18libcamera: pipeline: rkisp1: Fix usage of uninitialised variableLaurent Pinchart
Commit 1a813a5c3ab7 introduced usage of an uninitialised variable. Fix it. Fixes: 1a813a5c3ab7 ("libcamera: media_device: Handle media device fd in acquire() and release()") Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-05-18libcamera: camera: Fix std::ostringstream initialisationLaurent Pinchart
We use the std::ostringstream class to generate log messages in the Camera class. The stream is initialised with initial content, but is not opened without seeking to the end, which results in the content being overwritten immediately. Fix it by opening the stream with std::ios_base::ate. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-05-17libcamera: camera: Lock the pipeline handler in acquire()Niklas Söderlund
To allow more than one application using libcamera simultaneously there can be no overlap between which cameras are in use by which user. As a camera is part of a pipeline handler and there might be shared resources between all cameras exposed by that pipeline handler it's not enough to to only lock access to a single camera, all cameras from that pipeline need to be tied to the same process. Allow for this by locking the whole pipeline when one of its cameras is acquired by the user. Other processes can still enumerate and list all cameras in the system but can't acquire a camera from a locked pipeline handler. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-17libcamera: pipeline_handler: Add functions to lock a whole pipelineNiklas Söderlund
Add lock() and unlock() which are backed by the MediaDevice implementation and lock all media devices claimed by a pipeline handler instance. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-17libcamera: pipeline_handler: Keep track of MediaDeviceNiklas Söderlund
Instead of requiring each pipeline handle implementation to keep track of calling release() on its media devices upon deletion, keep track of them in the base class. Add a helper that pipeline handlers shall use to acquire a media device instead of directly interacting with the DeviceEnumerator. This also means that pipeline handler implementations do no need to keep a shared_ptr<> reference to the media devices they store locally as the PipelineHandler base class will keep a shared_ptr<> reference to all media devices consumed for the entire lifetime of the pipeline handler implementation. Centrally keeping track of media devices will also be beneficial to implement exclusive access to pipelines across processes. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-17libcamera: media_device: Add functions to lock device for other processesNiklas Söderlund
Add lock() and unlock() which are backed by lockf() and allow an instance of libcamera to claim exclusive access to a media device. These functions are the base of allowing multiple user of libcamera to coexist in the system without stepping on each other's toes. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-17libcamera: media_device: Make open() and close() privateNiklas Söderlund
All external callers to open() and close() have been refactored and there is no need to expose these functions anymore, make them private. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-17libcamera: media_device: Handle media device fd in acquire() and release()Niklas Söderlund
To gain better control of when a file descriptor is open to the media device and reduce the work needed in pipeline handler implementations, handle the file descriptor in acquire() and release(). This changes the current behavior where a file descriptor is only open when requested by the pipeline handler to that one is always open as long a media device is acquired. This new behavior is desired to allow implementing exclusive access to a pipeline handler between processes. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-17libcamera: media_device: Only read device information in populate()Niklas Söderlund
There is no reason to reread the MEDIA_IOC_DEVICE_INFO information every time the media device is opened. Move it populate() where it will be read once together the other information about the media device. 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>
2019-05-17libcamera: media_device: Open and close media device inside populate()Niklas Söderlund
Remove the need for the caller to open and close the media device when populating the MediaDevice. This is done as an effort to make the usage of the MediaDevice less error prone and the interface stricter. The rework also revealed and fixes a potential memory leak in MediaDevice::populate() where resources would not be deleted if the second MEDIA_IOC_G_TOPOLOGY would fail. 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>
2019-05-17libcamera: Always check return value of MediaDevice::acquire()Niklas Söderlund
In preparation for adding more responsibility to MediaDevice::acquire() remove unneeded calls to acquire() and release(), and make sure all needed calls to acquire() are checked and acted on. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-07qcam: format_converter: Add NV formats supportPaul Elder
Add support for some NV formats: - V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_NV21 - V4L2_PIX_FMT_NV16, V4L2_PIX_FMT_NV61 - V4L2_PIX_FMT_NV24, V4L2_PIX_FMT_NV42 Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-07qcam: format_converter: Add formatFamily enumPaul Elder
It is not sustainable to add a new flag for every new video format family (eg. YUYV, RGB, NV, MJPEG, etc), so add a formatFamily enum to indicate these in the FormatConverter. Note that formats are grouped into families based on if they are able to share a set of parameters for conversion. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-04qcam: format_converter: Add RGB formats supportLaurent Pinchart
Add support for the RGB format supported by VIMC (V4L2_PIX_FMT_BGR24, V4L2_PIX_FMT_RGB24 and V4L2_PIX_FMT_ARGB32). Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
2019-05-03libcamera: device_enumerator: add DeviceEnumeratorSysfs classPaul Elder
A udev-based device enumerator is not sufficient, since libudev is an optional dependency, or udev might fail. In these cases, we should fall back to using sysfs to enumerate devices. Add a DeviceEnumeratorSysfs class which is a specialization of DeviceEnumerator that uses sysfs to enumerate media devices on the system. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-05-03libcamera: v4l2_device: Increase error level for unsupported devicesKieran Bingham
If a component tries to open an unsupported device type, no error is presented unless debug is enabled. Report an error if an unsupported device type is opened to ease pipeline development. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-05-03libcamera: v4l2_device: Fix debug spacingKieran Bingham
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-30(q)cam: Unify naming of configurations in applicationsLaurent Pinchart
Name all instances of CameraConfiguration "config", and all instances of StreamConfiguration "cfg" accross the cam and qcam applications. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-04-30libcamera: pipeline: Unify naming of configurations in pipeline handlersLaurent Pinchart
Name all instances of CameraConfiguration "config", and all instances of StreamConfiguration "cfg" accross all pipeline handlers. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-04-30libcamera: Use the Size class through libcameraLaurent Pinchart
Several of our structures include width and height fields that model a size while we have a Size class for that purpose. Use the Size class through libcamera, and give it a toString() method like other geometry and format classes. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-04-30libcamera: pipeline_handler: Remove duplicated log from uvc and vimcLaurent Pinchart
The uvcvideo and vimc pipeline handlers print the requested resolution in their configureStreams() operation. This duplicates a generic log statement in the Camera::configureStreams() method, remove it. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-04-29libcamera: device_enumerator_udev: Include missing headerLaurent Pinchart
The makedev() macro is defined in sys/sysmacros.h, include the header explicitly. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-04-29libcamera: Don't ignore the return value of read() and write()Laurent Pinchart
The glibc read() and write() functions are defined with the __warn_unused_result__ attribute when using FORTIFY_SOURCE. Don't ignore their return value. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-28libcamera: camera: Log proposed configuration in streamConfiguration()Laurent Pinchart
The IPU3 and RKISP1 pipeline handlers log the camera configuration they propose in their streamConfiguration() methods. Other pipeline handlers are expected to log similar information, move it to the Camera class. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-04-28libcamera: camera: Check requests before queueing themNiklas Söderlund
Make sure all requests queued to a camera only contain streams which have been configured and belong to the camera. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
2019-04-27libcamera: Make libudev optionalLaurent Pinchart
libcamera depends on libudev for device enumeration. It is however useful to allow building documentation without requiring the dependency to be installed. Make the libudev dependency optional and compile the udev-based device enumerator out when libudev is not present. Note that while libcamera will compile without libudev, it will not be able to enumerate devices. A sysfs-based device enumerator is planned as a fallback but not implemented yet. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-27libcamera: v4l2_device: Prefix V4L2 direction in log messagesKieran Bingham
The V4L2Device will use the same deviceNode for two directions in the case of an M2M device. Add the direction to identify the queue direction on each instance. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-26libcamera: Remove outdated \todo commentsLaurent Pinchart
Some \todo comments are outdated and refer to tasks that have been completed. Remove them. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-26cam: options: Fix string concatenationLaurent Pinchart
Adding an integer value to a char pointer doesn't concatenate strings, it indexes in the pointed string. Fix it. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-26cam: options: Don't initialise variable-length arraysLaurent Pinchart
According to clang, variable-length arrays can't be initialised. Don't do so, and explicitly set the last element to 0 instead. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-26libcamera: v4l2_device: Buffer is not a structLaurent Pinchart
Buffer is a class, not a struct. Fix a variable declaration accordingly. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-26libcamera: Mark overridden functions with overrideLaurent Pinchart
Several overridden virtual functions are not marked with override. Fix it. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-26libcamera: log: Add a LogInvalid entry to LogSeverityLaurent Pinchart
enum LogSeverity values are assigned or compared to -1 to flag invalid log severities. This generates compilation warnings with clang. Fix it by adding an explicit LogInvalid entry to the enumeration. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-26libcamera: event_dispatcher_poll: Fix bitwise testLaurent Pinchart
Add missing parentheses to fix a bitwise test. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-26libcamera: Correct struct forward declarationsLaurent Pinchart
Several structures are forward-declarated as classes. Fix this by using the struct keyword where appropriate, or removing the forward declaration when not needed. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-26libcamera: utils: call secure_getenv() if it exists or workaround with ↵Giulio Benetti
issetugid() When secure_getenv() is not available, need to have a workaround. Check if secure_getenv() is present, otherwise call issetugid() on its place. Signed-off-by: Giulio Benetti <giulio.benetti@micronovasrl.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> [Kieran: include stdlib.h] Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-04-19libcamera: ipu3: Connect viewfinder's BufferReady signalJacopo Mondi
The viewfinder and main output require identical logic for buffer and request completion. Connect the viewfinder bufferReady signal to the slot and handle requests for both main output and viewfinder there. Update the slot logic to complete the request only when the last buffer has completed, and make sure to complete requests in the same order they have been queued to the pipeline handler. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2019-04-19libcamera: ipu3: Queue requests for multiple streamsJacopo Mondi
Add support for queueing requests for multiple streams in the IPU3 pipeline handler class. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2019-04-19libcamera: ipu3: Add multiple stream memory managementJacopo Mondi
Perform allocation and setup of memory sharing between the CIO2 output and the ImgU input and allocate memory for each active stream. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2019-04-19libcamera: ipu3: Use roles in stream configurationJacopo Mondi
Use and inspect the stream roles provided by the application to streamConfiguration() to assign streams to their intended roles and return a default configuration associated with them. Support a limited number of usages, with the viewfinder stream able to capture both continuous video streams and still images, and the main output stream supporting still images only. This is an artificial limitation until we figure out the exact capabilities of the hardware. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2019-04-19libcamera: ipu3: Create camera with 2 streamsJacopo Mondi
Sub-class the Stream class with an IPU3-specific implementation and create each IPU3 camera with two streams: 'output' and 'viewfinder' which represent the video streams from main and secondary ImgU output respectively. Rework stream configuration to handle the two video streams 'output' and 'viewfinder' separately. As the IPU3 driver requires viewfinder and stat video nodes to be started not to stall ImgU processing, configure 'output', 'viewfinder' and 'stat' regardless of the user-requested active streams. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2019-04-19libcamera: camera: Reset basefield to decimalJacopo Mondi
When logging the camera configuration, the same ostringstream instance is used to assemble a message describing configuration of all the configured streams. After the first stream configuration has been assembled, the use of std::hex modifies the ostringstream basefield, causing all successive integers values inserted in the stream to be expressed as hexadecimals. Fix that by resetting the stream's basefield to decimal, before assembling a stream configuration description. Before this patch: INFO Camera camera.cpp:615 (0) 640x480-0x3231564e (1) 140xa0-0x3231564e After this patch: INFO Camera camera.cpp:616 (0) 640x480-0x3231564e (1) 320x160-0x3231564e Fixes: 9c9078133216 ("libcamera: camera: Log requested configuration in configureStreams()") Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2019-04-19libcamera: stream: Document protected membersJacopo Mondi
Since commit: 4e1dc9004fca ("libcamera: stream: Make Stream inheritable") the private members of the Stream class have been turned into protected, to allows subclasses to access them. As Doxygen generates documentation for protected members (but not for private memebers), add documentation to the stream class for the 'bufferMap_' and 'configuration_' members. Fixes: 4e1dc9004fca ("libcamera: stream: Make Stream inheritable") Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
2019-04-19libcamera: Include header related to source file firstLaurent Pinchart
Include the header file corresponding to the source file in the very first position. This complies with the Google C++ coding style guideliens, and helps ensuring that the headers are self-contained. Three bugs are already caught by this change (missing includes or forward declarations) in device_enumerator.h, event_dispatcher_poll.h and pipeline_handler.h. Fix them. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>