Add a MAPPABLE data flag that hints that the fd in the data is mappable
with a simple mmap/munmap. Normally, DmaBuf is not mappable like that
unless explicitly indicated with this flag.
Set the MAPPABLE flag on the DmaBuf from v4l2 and libcamera fd.
When asked, mmap the buffer memory in all cases when the MAPPABLE
flag is set.
This solves the case where v4l2 has exported DmaBuf and is streaming to
node A and then node B links but doesn't get automatically mmaped
memory.
Fixes#3840
Pass on the device numbers property of libcamera to session managers, with they
are better equipped to filter the camera/video devices across v4l2 and libcamera.
A driver node should use the target_duration and target_rate to adjust
the quantum and rate when the graph starts.
The camera nodes don't currently support any of this and simply enforce
a specific rate and duration for the graph clock. Mark this with a
FIXME. Otherwise, pipewire will complain that the node is ignoring the
configured graph rate.
We should really look at the graph target rate/quantum and only produce
a buffer when it is inside the current graph cycle. This would make it
possible to join audio and camera nodes and have them be in sync.
According to https://docs.pipewire.org/page_dma_buf.html, i.e. announce
each format once with, once without `SPA_FORMAT_VIDEO_modifier`
property.
Note: currently libcamera always uses `DRM_FORMAT_MOD_LINEAR` (`== 0`),
so `pix.modifier()` returning `0` does not mean that no modifier is
supported.
This is needed for clients using the new DMABuf negotiation pattern,
such as gstpipewiresrc after 602aa7d5.
The drm format modifier value `0` is actually `DRM_FORMAT_MOD_LINEAR`,
a commonly used modifier. Unfortunately there appears to be no value
that can savely used as placeholder for "no value", as e.g.
`DRM_FORMAT_MOD_INVALID` is often used to indicate an implicit modifier.
Thus add an extra field that clearly indicates whether the modifier
value is set or not, add it to the util fuctions and use it for the
current only user, the libcamera backend.
Fixes 5a6da7d5e1
Closes https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/2943
`Transform::Rot90` means the client should rotate 90 deg. clockwise,
which matches `SPA_META_TRANSFORMATION_90`, i.e. the buffer was
rotated 90 deg. anti-clockwise. The flipped cases should be correct
though.
Also add the source value to the debug print for easier future
debugging.
Fixes fa799aac86
libcamera can detect camera transforms/rotation, e.g. from the device
tree, and makes that information usable for clients via
`CameraConfiguration::transform`.
Advertise this information via the VideoTransform meta so Pipewire
clients can adjust their output accordingly.
Rotated cameras are common in mobile devices such as the Pinephone Pro,
which was used to test this feature.
Find a free id from the available ids instead of just taking the current
number of devices, which would give assign the same id to multiple
cameras when: added 0, added 1, removed 0, added 1.
Pick the first format in the list of supported as something closest
to 640x480 instead of the lowest possible resolution.
Applications that don't suggest a default size will then get something
more sensible than a poster frame.
Previously, if "add_listener" was called on the monitor device, then it
did not necessarily emit events about all devices because it called
`enum_devices()` which does not emit events about already existing
devices. So the very first listener would get all existing devices,
but subsequent ones would not get events about the existence of devices
that have already been seen by the monitor. Fix that by simply emitting
events about all existing devices if the current listener is not the first.
libcamera's CameraManager runs the event handlers on its own thread,
thus synchronization is needed to ensure correct functionality.
Implement that by collecting hotplug events into a mutex protected queue
and signalling the main loop where they can be processed and the
"object_info" event can be safely emitted.
Using a shared_ptr removes the need for manually calling
`libcamera_manager_release()` to drop the reference as it is done
automatically whenever the shared_ptr is destroyed or reset.
Previously, the libcamera manager `impl` object was neither properly
constructed neither properly destructed. As a consequence, for example,
the shared pointers in the `devices` array weren't properly destructed,
although this has been somewhat mitigated by a previous change
that modifed `clear_devices()`.
Previously, the "impl" object was never properly constructed or
destructed, but it more or less worked out since the memory was initialized
to zero bytes and each member had trivial constructors. Except std::shared_ptr,
but an all zero storage happened to be equivalent to a default constructed
shared_ptr.
However, there was the still the problem that the shared_ptr was never
destructed, so it kept the referenced `Camera` object alive, which lead
to memory leaks.
An additional, somewhat unrelated change is that the "props" struct
is removed, and the device identifier is now stored in an `std::string`.
The reason is that `CameraManager::get()` already takes a const std::string reference,
so an std::string must be constructed in any case, so we might as well
take advantage of that and use `std::string` in the "impl" object as well.
Furthermore, wrap the `impl` struct in an anonymous namespace
to avoid name resolution problems.