If we don't get a link on a stream, we might never send a create stream
reply. The client handles this fine by timing out after 30s and dropping
the stream, but the server holds on to the pw_stream forever (or until
the client quits).
Let's add a timer to clean up such streams on the server.
Fixes: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4901
Wireplumber loads the libcamera nodes into the pipewire server.
We need to remove the RestrictNamespaces option from the service file
to allow libcamera to load sandboxed IPA modules.
Add a port.exclusive flag and inherit the value from the node.exclusive
flag if not otherwise specified.
Make it so that exclusive ports can only be linked once. This is
important for explicit sync where there can be only one producer and one
consumer in order to signal the timeline objects correctly.
The property will be dropped from the filtered result when one of the
pods to filter does not have the property.
This can be used as a feature mask. If side A provides a flags property
and B doesn't, the property will be removed from the result. Without the
flag, property A would be added and it would not be possible to see if
filtering happened (when B had compatible flags) or not.
pw_stream now handles the other (output) latency for us, it will keep
the param and report it. If we are not interested in upstream latency we
don't have to parse and store it and we can just be concerned with the
latency we report on our input port (input latency).
Update the scheduling doc with some information about how async
scheduling works. Also add something about the latency.
Async links add 1 quantum of latency so take that into account when
aggregating latencies.
Also a source directly linked to an async node does not add latency
(we evaluate the tee before incrementing the cycle so that it effectively
is executed in the previous cycle and consumed immediately by async
nodes). We can do this because the driver source always provides data
before the async node, and never concurrently.
Add a listener to the link for the node driver change as well because
that can now influence the latency for async nodes.
Add an option to make a property with specific flags. Do this by
changing the parser and builder to see the invalid property as an escape
sequence followed by the property key and the flags.
This flag is set by the producer and should be cleared by the consumer
when it promises to signal the release point.
When a consumer dequeues a buffer with the flag set, it should assume
the client is not going to signal the release point and so it should
reuse the buffer right away. This can only happen when the client
didn't dequeue the buffer at all (killed, timeout, error, ...) or when
it dequeued and queued the buffer without clearing the flag.
See #4885
do_node_unprepare runs in both the server and the client when a node is
stopped. On the server size, set the status to FINISHED and trigger any
targets. This ensures the node will not be scheduled in this cycle
anymore. We have to do this because we can't know if the node is still
alive or not.
When the client receives the stop message, it will unprepare and set the
status to INACTIVE. This ensures the driver will no longer trigger the
node. If the server didn't already trigger the targets, do this in the
remote node then.
This avoid a race where both the client and the server are setting the
status and if the INACTIVE state is set by the server, it might stall
processing of the client.
Fixes#4840
The docs say that a requested size of 0 can be returned and it means
that there is no suggestion for the size.
Make this so by decoupling the requested size value and the triggering
of the process callback. If we have no rate_match and no quantum
(because the driver didn't set it) we still want to schedule with a 0
requested size.
Previously the pointer was determined as follows:
mm->this.ptr = SPA_PTROFF(m->ptr, range.start, void);
however, when `pw_map_range` is calculated, `pw_map_range::start` is the offset
from the beginning of the first page, starting at `pw_map_range::offset`.
This works correctly if `memblock_map()` runs because that will map the file
with expected offset, so using `range.start` is correct.
However, when a mapping is reused (i.e. `memblock_find_mapping()`) finds something,
then `range.start` is not necessarily correct. Consider the following example:
* page size is 10
* one memblock with size 20 (2 pages)
* the applications wants to mappings:
* (offset=5,size=10)
* (offset=15,size=5)
After the first request from the application, a `mapping` object is created
that covers the first two pages of the memblock: offset=0 and size=20. During
the second request, the calculated `pw_map_range` is as follows:
{ start = 5, offset = 10, size = 10 }
and the only previously created mapping is reused since (0 <= 5) and (10 <= 20). When
the pointer of the mapping is adjusted afterwards it will be incorrect since `m->ptr`
points to byte 0 on page 0 (instead of byte 0 on page 1 -- that is assumed). Thereforce
the two will unexpectedly overlap.
Fix that by using `offset - m->offset` when adjusting the mapping's pointer. Also move
the `range` variable into a smaller scope because it only makes sense there. And add
a test that check the above previously incorrect case.
Fixes: 2caf81c97c ("mem: improve memory handling")
Fixes#4884
Align RX of streams in same ISO group:
- Ensure all streams in ISO group have same target latency also for BAP
Client
- Determine rate matching to ISO group clock from RX times of all
streams in the group
- Based on this, compute nominal packet RX times, and feed them to
decode-buffer instead of the real RX time. This is enough for
sub-sample level sync.
- Customise buffer overrun handling for ISO so that it drops data to
arrive exactly at the target, for faster convergence at RX start
The ISO clock matching is done based on kernel-provided packet RX times,
so it has unknown offset from the actual ISO clock, probably a few ms.
Current kernels (6.17) do not provide anything better to use for the
clock matching, and doing it properly appears to be controller
vendor-defined (if possible at all).
Take resampler delay into account when computing the buffer fill level,
including the fractional part.
If decode-buffer is now fed nominal packet reference times in
write_packet(), it converges the total buffer + resampler latency to the
target at sub-sample accuracy.
This is needed for aligning RX of ISO streams in the same group, so that
e.g. stereo pair alignment is achieved even though the streams have
separate resamplers. Resampler phases get aligned via independent rate
matching.
The rate matching calculations are done in the system clock domain. If
the driver ticks at a different rate, the correction factor needs to be
adjusted by the rate_diff.
setup_matching() also needs to be before spa_bt_decode_buffer_process():
as follower we should use rate matching value calculated on the
*previous* cycle, because this is what driver is doing when it adjusts
it tick rate.
Based on testing, ALSA FireWire drivers introduce additional latency
determined by the buffer size.
Report that latency.
Pass device.bus to the node, so it can recognize firewire.
FireWire ALSA driver latency is determined by the buffer size and not the
period. Timer-based scheduling is then not really useful on these devices as
the latency is fixed.
In pro-audio profile, enable IRQ scheduling unconditionally for these
devices, so that controlling the latency works properly.
See #4785
Some devices (FireWire) fail to produce audio if period count is < 3,
and also have small buffer size. When quantum is too large, we might
then get too few periods and broken sound.
Set minimum for the period count in ALSA, to determine the maximum
period size we can use. If smaller than what we were going to use, round
down to power-of-2.
See #4785
With the removal of `SPA_DATA_MemPtr` support, this member is no longer used.
Fixes: b948ffdb25 ("spa: libcamera: source: remove `SPA_DATA_MemPtr` support")
On production systems, having a constant high latency is favored over
dynamically adjusting it in order to optimize for low latency,
because every time a dynamic adjustment happens, there's a glitch.
This adds an option to let the user specify the exact amount of latency
they want.
The hardcoded latency of 512/<rate> is quite low on some ALSA devices.
Instead of forcing that latency onto the graph, just don't set it at all
unless it originates from the BAP presentation delay. That means that
the functionality remains the same for BAP but changes for A2DP to favor
the preferred quantum of the ALSA sink (or whatever is the driver).
Also, avoid setting an empty string ("") latency and rate in the cases
where it's not defined. This allows users to override those properties
through the wireplumber monitor rules if they need to.
Currently the v4l2 and libcamera plugins map `SPA_PROP_exposure` in incompatible
ways. So change the v4l2 mapping to `V4L2_CID_EXPOSURE_ABSOLUTE` because at least
that is in units of time (a step closer to addressing #4697), and because that
is more relevant for UVC cameras.
Also change the pipewire-v4l2 translation layer.
Rework how the monitor mode works. Instead of having separate paths for
the list and monitor mode, reuse the list mode. We simply mark all
changes and then list the changes in a loop.
This makes it possible to accumulate some updates and print them
together.
Add a -t option to list the latency params on a port.