Make a ringbuffer per driver because each driver might run in a
different threads and because a shared ringbuffer can not be written to
from multiple threads. Assemble all the driver stats into one buffer
before sending out the profile info.
Remove the context_driver events and replace them with realtime node
events. The problem is that the realtime node events are emitted from
the node data thread, which can be different for each node and
aggregating them into context_driver events is not a good idea.
It's also nice for the stream drained event, which no longer needs to go
through the context_driver events.
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.
First update some stream defaults, then apply generic property updates.
Before connecting, fill in some more default with the flags and the
direction of the stream, then evaluate the rules, then overwrite with
environment values.
This ensure that the rules can also use the flags and direction used
during _connect().
See #3355
Enforce that the owner client of the output node can see the input node
and vice versa.
This works around an issue where the session manager performs a link
between nodes that should not be linked, like when doing screensharing
and the portal has set permissions to only see the screenshared stream,
wireplumber will link to the camera when the target.object is not set.
See also wireplumber#218
This has unfortunately the downside that patchbays like helvum will also
not be able to link those nodes. We should probably add a new link
permission to allow this explicitly.
This reverts commit 21d16b1ad5.
The change causes the sound of videos to be way out of sync when streaming from Fedora to Sonos.
It seems the issue is a device-specific quirk, and the change cannot be applied universally to all devices,
thus reverting until a better solution is found that does not affect other devices.
For all the modules that include the private header we require that the
library and compiler versions match.
Otherwise we might end up poking into new or old fields that got moved or
changed in the private struct and crash.
See #3243
Remove some includes of private.h
Add some methods to get the mempool of client and context so that we can
remove direct access.
Move some things around.
Use methods to get pw_loop variables.
See #3243
systemd, dbus-broker, and many glib applications heavily
utilize the GNU C attribute "cleanup" to achieve C++ RAII-like
semantics for local resource management. This commit introduces
essentialy same mechanism into pipewire.
At the moment, this is inteded to be a strictly private API.
free() and close() as cleanup targets are sufficiently common
to warrant their own special macros:
spa_autofree char *s = strdup(p);
// will call `free(s)` at the end of the lifetime of `s`
spa_autoclose int fd = openat(...);
// will call `close(fd)` if `fd >= 0` at the end of the lifetime of `fd`
However, with `spa_auto()` or `spa_autoptr()` it is possible to define
other variables that will be cleaned up properly. Currently four are supported:
spa_autoptr(FILE) f = fopen(...);
// `f` has type `FILE *`
// will call `fclose(f)` if `f != NULL`
spa_autoptr(DIR) d = opendir(...);
// `d` has type `DIR *`
// will call `closedir(d)` if `d != NULL`
spa_autoptr(pw_properties) p = pw_properties_new(NULL, NULL);
// `p` has type `struct pw_properties *`
// will call `pw_properties_free(p)`
spa_auto(pw_strv) v = pw_split_strv(...);
// `v` has type `char **`
// will call `pw_strv_free(v)`
It is possible to add support for other types, e.g.
SPA_DEFINE_AUTOPTR_CLEANUP(pw_main_loop, struct pw_main_loop, {
// the pointer can be accessed using `*thing`
// `thing` has type `struct pw_main_loop **`
spa_clear_ptr(*thing, pw_main_loop_destroy);
})
spa_autoptr(pw_main_loop) l = ...;
// `l` has type `struct pw_main_loop *`
// will call `pw_main_loop_destroy(l)`
or
SPA_DEFINE_AUTO_CLEANUP(spa_pod_dynamic_builder, struct spa_pod_dynamic_builder, {
// `thing` has type `struct spa_pod_dynamic_builder *`
spa_pod_dynamic_builder_clean(thing);
})
spa_auto(spa_pod_dynamic_builder) builder = ...
// `builder` has type `struct spa_pod_dynamic_builder`
// will call `spa_pod_dynamic_builder_clean(&builder)`
The first argument is always an arbitrary name. This name must be passed to
`spa_auto()` and `spa_autoptr()` as it is what determines the actual type
and destructor used. The second parameter is the concrete type. For
`SPA_DEFINE_AUTO_CLEANUP()` this is the concrete type to be used, while for
`SPA_DEFINE_AUTOPTR_CLEANUP()` it is the concrete type without the
outermost pointer. That is,
SPA_DEFINE_AUTOPTR_CLEANUP(A, foo, ...)
SPA_DEFINE_AUTO_CLEANUP(B, foo, ...)
spa_autoptr(A) x; // `x` has type `foo *`
spa_auto(B) y; // `y` has type `foo`
A couple other macros are also added:
spa_clear_ptr(ptr, destructor)
// calls `destructor(ptr)` if `ptr != NULL` and sets `ptr` to `NULL`
spa_clear_fd(fd)
// calls `close(fd)` if `fd >= 0` and sets `fd` to -1
spa_steal_ptr(ptr)
// sets `ptr` to `NULL` and returns the old value,
// useful for preventing the auto cleanup mechanism from kicking in
// when returning the pointer from a function
spa_steal_fd(fd)
// sets `fd` to -1 and returns the old value
When we destroy a node, we need to remove the node as a current
driver peer.
Not doing this has 2 problems:
- remote drivers still trigger our node
- the client-node does not clean up the memid for the activation and
we might reuse it later for a new node with the same fd.
See #3316
We have SPA_ID_INVALID mix id for all ports to handle the formats and
buffers, we don't need to init/release the mix for this or else our
n_mix accounting is wrong and we might not clear the format right.