Always reevaluate the rate matching even when we did not change the
follower state.
It is possible that we were a follower from some node with the same
clock and now become a follower of a node with a different clock. The
follower state doesn't change but we need to activate the rate matching
logic in that case.
Fixes rate matching in pro audio (playback) when capture and playback
are moved to another driver.
After we set the format, probe if we can do EXPBUF and enable/disable
the ALLOC_BUFFERS flag on the port.
This should gracefully handle the case where EXPBUF is not available.
Fixes#3821
When we try to alloc buffers but EXPBUF is not supported, make sure to
clear the alloc_buffers flag so that the caller can try again with
allocated buffers instead.
See #3821
Move some of the tracking code for the DLL to where it is used.
Add resync.ms (default 10) option at which we give up rate adjusting
and instead do a hard resync. This results in a jump in the position
of the graph clock.
We can increase the MAX_LATENCY again if we increase the amount of
buffers when we are using a small buffer.
Normally we ask for 4 * quantum-limit as the buffer. This should be good
to use 1 buffer and quantum-limit as the quantum with enough headroom
to not run out of buffers.
If we are however using less buffer-frames we need to be careful and
allocate an extra buffer. Imagine using a buffer of 4096 frames, we can
support a quantum of up to 2048 frames if we use 2 buffers.
See #3744
Half of the buffersize is not enough to support as a max-quantum, we
need to divide by (4 * frame_scale) to allow some headroom and account
for the DSD scaling. We do the same calculation to suggest a buffer size
using the quantum-limit.
See #3744
When the filter has no format property, just enumerate all possible
framerates. Handle error case where the filter has the wrong type.
Makes gst-launch gstpipewiresrc ! video/x-raw ! fakesink work.
See #1793
Actually count the number of frame fractions we add. If we added 0, we
don't have any supported framerate that intersects with the filter and we
try the next frame size.
See #1793
Unknown transports visible in DBus usually belong to a different
sound server instance that is talking to BlueZ.
Explain this in the warning message that we log, so that people can more
easily understand why things are not working.
When freewheeling we will immediately schedule a new graph cycle when we
get a process call because the graph completed.
When the process call is not done, because of some xrun or
because some node was removed that causes the graph to fail completion,
The next cycle will happen after a timeout.
This timeout was calculated as the ideal wakeup time (after a quantum of
time) and would accumulate for each timeout. The result is that the
timeout ended up far in the future and would stall the freewheel driver
for a long time.
Fix this by always setting the next timeout to wakeup time + freewheel.timeout
seconds. Also add a config property for the timeout (10 seconds, like
jack2 by default).
Primark True Wireless earbud doesn't support sbc-xq. Having it
enabled causes bluez to enter into a loop enabling/disabling
the device dozens of times per minute, making it unusable.
As part of the setup for IRQ based scheduling, a period event
was installed. Not only is a timer based polling unecessary for
IRQ scheduling, depending on the state of the system, the timer
could fire far enough from the IRQ, causing alsa wakeup events
with no data in the ring buffer. Pipewire would identify these
events as an "early wakeup", adding an extra quantum of time
to the next_time estimate, skewing the clock and causing issues
with apps that depend on precise timing.
Update the started and ready state after we suspend/pause the node so
that we don't complain if scheduling happens between setting the fields
and actually stopping the follower.
Also only complain when the scheduling happens when the node is not
ready. It is possible that the node is scheduled before we manage to set
the started field.
Move the driver and warned bits after the int field in the struct so
that they are placed in separate memory.
Otherwise, a write from the data thread might race with a write from the
main thread and leave the bits in the wrong state.
This reverts commit 49cdb468c2.
We should not do this, the nsec field should be relatable to the clock
monotonic time. If we use the estimated time, without actually using it
as a timer, we might end up with a wakeup time in the future compared to
the MONOTONIC clock time.
Instead, you can use the estimated current time simply by subtracting
the rate corrected duration from the next_nsec. This is really only
useful for some selected use cases (like in the JACK library).
This fixes some issues where in pro-audio mode, a client would try to
compare the current MONOTONIC time to nsec and find that it is in the
past.
This commit was done in an attempt to fix#3657 but it turned out the
real problem was something else.
The alsa sequencer rate matching was not actually working correctly.
It would compare the previous queue time with the current time and
compare that to the quantum. This would include uncorrected errors from
jitter and would result in the timeouts being scaled in the wrong
direction forever.
Instead, calculate an ideal queue time and compare our current queue
time against that. We then use the correction to scale the timeout or
the next queue time prediction.
Also use the predicted time as the base time for the event timestamps.
this results in less jitter.
Fixes#3657
sync_mixer() calls d->set_volume(d, &d->real_volume);
which makes v and &dev->real_volume point to the same memory area
and valgrind complains:
Source and destination overlap in memcpy(0xcc53e2c, 0xcc53e2c, 260)
at 0x488CFA0: __GI_memcpy (vg_replace_strmem.c:1121)
by 0xBB0803F: set_volume (acp.c:1143)
by 0xBB0EDCB: acp_device_set_port (acp.c:1897)
by 0xBA9CD87: impl_set_param (alsa-acp-device.c:757)
because the compiler apparently implicitly converts this into a memcpy()
and memcpy(3) explicitly says "The memory areas must not overlap."
Don't try to multiple the max_buffer_size with the frame scale or else
we might try to set a min_buffer_size larger than the max_buffer_size.
Instead, use the frame_scale only to scale the quantum_limit and then
clamp against the max_buffer size.
See #3000
When we don't have the thread id yet, don't add the pollfds yet
but wait until we do our first wait operation.
Use flags for eventfd. We can use this to communicate between all kinds
of threads with read/write.
Use evl_init() in the init function, don't attach the main loop, just
the thread that dos the first poll.
Some devices appear to set Supported_Max_Codec_Frames_Per_SDU == 1 while
claiming they support two channels per stream, which is then not
possible.
In this case, limit the number of channels by the number of frames per
SDU when selecting.
Also adjust PAC sorting.
It doesn't make sense to hang these on the data loop, so let's have
these on the main loop instead. Also avoids a potential crash while
removing them (since removal happens on the main loop and the data loop
might be polling while we're doing the remove).
added cleanup of unused variables and fix warning about missing initializers
to resolve build warnings in pipewire-rs
Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Don't use the current time as the nsec field in the graph clock because
it can jitter a lot. Instead, use the smoothed next_time, like we do
for timer based scheduling.
Since we track the current time against the rate converted ideal time,
lock on to the first timestamp when we reset the dll.
See #3657
Don't return the value of the last snd_pcm_resume() call because that
might be -ENOSYS when resume is not implemented for the card and then
the non-error (because we used drop/prepare later) propagates and
logs an error.