Commit graph

128 commits

Author SHA1 Message Date
Carlos Rafael Giani
0121bdc475 module-rtp: Lower missing timeout log line from warn to trace
A warning is not warranted in this case, and this log line can spam
the logs, so set it to trace.
2026-03-30 23:45:34 +02:00
Wim Taymans
60062432b8 module-rtp: handle the send_packet/feedback as callbacks
They are emited from the streaming thread and therefore can be emitted
concurrently with the events on the main thread. This can cause crashes
when the hook list is iterated.

Instead, make those events into callbacks that are more efficient,
and threadsafe.
2026-03-26 09:34:45 +01:00
Wim Taymans
ea28343166 midi: don't convert Midi in nodes
Avoid doing conversions in the nodes between Midi formats, just assume
the imput is what we expect and output what we naturally produce.

For ALSA this means we produce and consume Midi1 or Midi2 depending on the
configurtation.

All of the other modules (ffado, RTP, netjack and VBAN) really only
produce and consume MIDI1.

Set the default MIDI format to MIDI1 in ALSA.

Whith this change, almost everything now produces and consumes MIDI1
again (previously the buffer format was forced to MIDI2).

The problem is that MIDI2 to and from MIDI1 conversion has problems in
some cases in PipeWire and ALSA and breaks compatibility with some
hardware.

The idea is to let elements produce their prefered format and that the
control mixer also negotiates and converts to the node prefered format.
There is then a mix of MIDI2 and MIDI1 on ports but with the control
port adapting, this should not be a problem.

There is one remaining problem to make this work, the port format is
taken from the node port and not the mixer port, which would then expose
the prefered format on the port and force negotiation to it with the
peer instead of in the mixer.

See #5183
2026-03-25 11:59:43 +01:00
Wim Taymans
6bf81ebe59 modules: align rtp_timestamps for sender
When the driver changes, the clock position can also change and there
would be a discont in the rtp_timestamp.

This is not usually a problem except in RAOP mode where the base rtp
timestamp is negotiated and anything that deviates too much is to be
discarded.

If we are not using direct_timestamp for the sender, make sure we always
keep the rtp_time aligned to avoid this problem.

See #5167
2026-03-17 14:05:09 +01:00
Wim Taymans
f4587ea434 modules: improve debug in RTP 2026-03-17 14:05:09 +01:00
Carlos Rafael Giani
642504f5f9 module-rtp: Compensate for stream resampler effects in RTP sink node 2026-02-03 09:07:48 +01:00
Carlos Rafael Giani
6192c11038 module-rtp: Convert clock pos to RTP time in RTP source and factor in ASRC
This can easily be overlooked if the RTP rate equals the clock rate, which
is fairly common (for example, RTP rate and clock rate both being 48 kHz).

And, if an ASRC is active, and converting the output of the RTP source
node, the resampler's delay need to be taken into the account as well.
2026-02-03 09:07:48 +01:00
Stanislav Ruzani
e874f705a9 module-rtp: clear ringbuffer when stream stops to prevent old packets
Clear the ringbuffer in stream_stop() when processing stops to prevent old invalid packets
from being sent when processing resumes via rtp_audio_flush_packets().

This ensures a clean state when the stream restarts.
2026-02-03 09:07:48 +01:00
Carlos Rafael Giani
5d7f21f130 module-rtp: Improve rtp_audio_flush_packets() logging 2026-02-03 09:07:48 +01:00
Carlos Rafael Giani
9f0dc9c1af module-rtp: Update ringbuffer indices upon resync with proper API calls 2026-02-03 09:07:48 +01:00
Carlos Rafael Giani
543000151f module-rtp: Handle unsigned 32-bit integer overflow in constant delay mode 2026-02-03 09:07:48 +01:00
Carlos Rafael Giani
413f5762c4 module-rtp: Clear ringbuffer in constant delay mode
Clearing the ring buffer is important not only in the direct timestamp
mode, but also in the constant delay mode, since missed packets can lead
to gaps in the ring buffer. These gaps may have stale data inside if the
ringbuffer is not cleared after reading from it.
2026-02-03 09:07:48 +01:00
Carlos Rafael Giani
95970e539e module-rtp: Fix invalid ring buffer read attempts in direct timestamp mode
In corner cases where the read and write pointers are very close, it may
not be possible to read out all the wanted samples. This can for example
happen when there is a jump in the graph driver position. Currently, the
code reads the wanted number of samples out of the ring buffer regardless
of the write and read pointer positions. It does so even when the read
pointer is ahead of the write pointer (that is, an underrun occurs).

Fix this by checking the fill level and reading only the available amount
of samples if that amount is less than the wanted amount. The remaining
space in the target buffer is then filled with nullbytes.
2026-02-03 09:07:48 +01:00
Carlos Rafael Giani
a32e6e108c Revert "module-rtp: Remove device_delay from timestamp math"
This reverts commit dcdc19238b.

Reverting this because it caused big sync errors of ~62 ms in test setups.
Further discussions about this can be found here:

https://gitlab.freedesktop.org/pipewire/pipewire/-/merge_requests/2666

Followup commits modify the device delay application (by scaling it),
which is another reason why this needs to be reverted.
2026-02-03 09:07:36 +01:00
Alexander Stephens
c74acf6c25 module-rtp: Fix timestamp integer overflow 2026-01-16 11:06:21 +00:00
Alexander Stephens
dcdc19238b module-rtp: Remove device_delay from timestamp math 2026-01-16 11:06:21 +00:00
Wim Taymans
ff0bc22cb1 modules: support audio.layout where we can 2025-10-30 12:29:31 +01:00
Carlos Rafael Giani
955c9ae837 module-rtp: Get the current stream time in a reusable manner
That way, redundant pw_stream_get_nsec() and clock_gettime()
calls can be avoided.
2025-10-27 22:40:22 +01:00
Wim Taymans
5e1e3fca1e modules: handle format parsing errors 2025-10-23 18:01:35 +02:00
Wim Taymans
f453b1545d audio: don't use SPA_AUDIO_MAX_CHANNELS in some places
When we know the max size of the array, just use this instead of the
SPA_AUDIO_MAX_CHANNELS constant.
2025-10-20 18:31:17 +02:00
Carlos Rafael Giani
65e49b38d1 module-rtp: Add process.latency.from.sess prop to set process latency 2025-09-24 22:54:06 +02:00
Carlos Rafael Giani
63df661eff module-rtp: Handle Latency and ProcessLatency in stream 2025-09-24 22:54:06 +02:00
Carlos Rafael Giani
caf72fd9bc module-rtp: Synchronize access to timer_running flag 2025-08-25 10:33:50 +00:00
Carlos Rafael Giani
37e597ff0a module-rtp: Replace "started" boolean with internal state enum
The started boolean is insufficient to fully cover the possible internal
states. For this reason, it needs to be replaced by an enum that covers
these states.

Also, due to potential access by both the dataloop and the mainloop,
access to that internal state needs to be synchronized.

Finally, a variable "internal_state" makes for code that is easier to
read, since it emphasizes that this is state that is fully internal
inside the stream (and is not visible to the rtp-sink and rtp-source
modules for example).
2025-08-25 10:33:50 +00:00
Carlos Rafael Giani
3476e77714 module-rtp: Replace state_changed callbacks
The state_changed callbacks fulfill multiple roles, which is both a problem
regarding separation of concerns and regarding code clarity. De facto,
these callbacks cover error reporting, opening connections, and closing
connection, all in one, depending on a state that is arguably an internal
stream detail. The code in these callbacks tie these internal states to
assumptions that opening/closing callbacks is directly tied to specific
state changes in a common way, which is not always true. For example,
stopping the stream may not _actually_ stop it if a background send timer
is still running.

The notion of a "state_changed" callback is also problematic because the
pw_streams that are used in rtp-sink and rtp-source also have a callback
for state changes, causing confusion.

Solve this by replacing state_changed with three new callbacks:

1. report_error : Used for reporting nonrecoverable errors to the caller.
   Note that currently, no one does such error reporting, but the feature
   does exist, so this callback is introduced to preserve said feature.
2. open_connection : Used for opening a connection. Its optional return
   value informs about success or failure.
3. close_connection : Used for opening a connection. Its optional return
   value informs about success or failure.

Importantly, these callbacks do not export any internal stream state. This
improves encapsulation, and also makes it possible to invoke these
callbacks in situations that may not neatly map to a state change. One
example could be to close the connection as part of a stream_start call
to close any connection(s) left over from a previous run. (Followup commits
will in fact introduce such measures.)
2025-08-25 10:33:50 +00:00
Carlos Rafael Giani
2f22c1d595 module-rtp: Stop any ongoing timer when starting stream 2025-08-25 10:33:50 +00:00
Wim Taymans
e35a8554f8 control: improve UMP to Midi conversiom
Improve the spa_ump_to_midi function so that it can consume multiple UMP
messages and produce multiple midi messages.

Some UMP messages (like program changes) need to be translated into up
to 3 midi messages. Do this byt adding a state to the function and by
making it consume the input bytes, just like the spa_ump_from_midi
function.

Adapt code to this new world. This is a little API break..
2025-08-19 18:33:59 +02:00
Carlos Rafael Giani
97a1609b29 module-rtp: Reset ring buffer contents when stream starts 2025-08-05 17:54:56 +00:00
Carlos Rafael Giani
c9a8b8629f module-rtp: Limit actual max buffer size to an integer multiple of stride
Opus and MIDI code get TODOs added, since it is currently unclear how to
implement that fix for them.
2025-08-05 17:54:56 +00:00
Carlos Rafael Giani
e5be9cce4f module-rtp: Reorder sync checks and resynchronization code
This fixes the case when synchronization is established but actually not
valid anymore. In such a case, the code would _first_ write to the ring
buffer (at the wrong position due to the invalid sync), and _then_ detect
the bogus synchronization. Reorder the code blocks to _first_ check the
current sync, then resynchronize if neeeded (or perform initial sync if
no sync is established yet), and _then_ write to the ring buffer.
2025-08-05 17:54:56 +00:00
Carlos Rafael Giani
b8d98d03fe module-rtp: Fix timestamp check and add discontinuity check
Until now, the timestamp check was comparing the timestamp delta against
the value of the "quantum" variable. However, the timestamps use clock
samples as units, while the "quantum" variable uses nanoseconds. The
outcome is that this check virtually never returned true. Use the
spa_io_clock duration instead of that quantum nanosecond duration to make
the check actually work.

Also, do not just rely on vast timestamp deltas to detect discontinuities;
instead, check first for the presence of the SPA_IO_CLOCK_FLAG_DISCONT
flag to detect said discontinuities.
2025-08-05 17:54:56 +00:00
Carlos Rafael Giani
2a460e18e3 module-rtp: Rename timestamp to actual_timestamp for clarity 2025-08-05 17:54:56 +00:00
Wim Taymans
8495bffee5 modules: use safer pod parsing for control sequence 2025-07-31 11:50:11 +02:00
Carlos Rafael Giani
91ebfac75b module-rtp: Clear after reading in direct timestamp mode 2025-07-29 17:24:09 +02:00
Wim Taymans
42b779974c module-rtp: don't leak opus codec and ptp_sender
Add a deinit() function and use it to free the opus codec we created in
init().

Also free the ptp_sender when it was created.
2025-07-24 13:16:15 +02:00
Carlos Rafael Giani
2bcc8589fa module-rtp: Fix and improve direct timestamp mode and documentation
Direct timestamp mode was incorrectly using over/underrun detection logic
and fill level tracking logic that is actually meant for the other mode
(referred to from now on as "constant latency mode"). Over/underruns are
tracked implicitly in the direct timestamp mode, and the absolute fill
level is not relevant in that mode, since the latency is not needed to
be constant then.

Also improve log lines and the RTP module documentation to define these
buffer modes clearly and explain their differences and use cases.

Opus and MIDI code get TODOs added, since their direct timestamp mode
implementations still may be incorrect. Fixing those will be done in
a separate commit.
2025-07-24 07:28:53 +00:00
Martin Geier
f8b0d0a43c rtp: include stream delay to a read position
When a stream has some delay, a time t1 + delay has to be read in time
t1 to play it when expected.
Decrease target_buffer by delay to start playback sooner, so sound
is played at correct time when delay is applied.

Signed-off-by: Martin Geier <martin.geier@streamunlimited.com>
2025-07-24 07:28:53 +00:00
Demi Marie Obenour
b8e29d471b module-rtp: Fix bounds checks in MIDI parsing
These are potential security problems.
2025-07-15 10:46:10 +02:00
Wim Taymans
47ee9ef10a module-rtp: set the EMPTY flag on empty buffers
And make sure other flags are reset.
2025-07-03 20:57:19 +02:00
Sam James
2cec77e7df *: unify config.h handling
config.h needs to be consistently included before any standard headers
if we ever want to set feature test macros (like _GNU_SOURCE or whatever)
inside. It can lead to hard-to-debug issues without that.

It can also be problematic just for our own HAVE_* that it may define
if it's not consistently made available before our own headers. Just
always include it first, before everything.

We already did this in many files, just not consistently.
2025-05-30 10:24:13 +00:00
Wim Taymans
564c9b1ba5 Use "8 bit raw midi" for control ports again
There is no need to encode the potential format in the format.dsp of
control ports, this is just for legacy compatibility with JACK apps. The
actual format can be negotiated with the types field.

Fixes midi port visibility with apps compiled against 1.2, such as JACK
apps in flatpaks.
2025-05-23 16:46:13 +02:00
Wim Taymans
722776cf65 Remove some hardcoded channel number values
Mostly related to the number of channels.
2025-04-04 15:46:03 +02:00
Wim Taymans
e825a6ae6c modules: reduce some errors from warn to info
Some of the more common errors (caused by packet loss, network jitter, ...)
should be reported with INFO unless there is some indication about how
to fix the problem.

Fixes #4559
2025-02-18 16:24:52 +01:00
Wim Taymans
cfc8d414a9 module-rtp: fix SSRC warnings
Fix indentation and also suppress the SSRC warning for other formats
than audio.
2025-02-17 10:21:17 +01:00
Arun Raghavan
25e58995f5 module-rtp-sap: Silently ignore other SSRCs if we know the receiver SSRC
If we know the receiver SSRC from the SAP, we can happily ignore packets
on other SSRCs.
2025-02-15 22:32:12 -05:00
Arun Raghavan
13e3918f81 module-rtp-sap: Publish sender SSRC if we have it
Can be handy on the receiver side.
2025-02-15 17:58:34 -05:00
Wim Taymans
830bd19ca2 rtp: take into account ipv4/ipv6 when calculating header size
Calculate the header_size based on the IP version instead of using a
hardcoded value.

Fixes #4524
2025-01-24 12:45:05 +01:00
Wim Taymans
96d593cc34 rtp: idle the source when in timeout
Idle the source when no packets are received and resume when new packets
arrive.

Add a stream.may-pause property to pause the stream when no packets are
received during the timeout window.

Make sure the rtp.streaming property is updated correctly and as soon as
we get the first packet.

Fixes #4456
2025-01-21 16:51:31 +01:00
Arun Raghavan
974117f41a module-rtp: Fix previous typo fix
We want to track the difference between the PTP timestamp (now) and the
last RTP send, not the synthesized next RTP timestamp (which will always
be smoothly incrementing).
2024-12-31 15:24:46 -05:00
Arun Raghavan
c143e89118 module-rtp: Fix typo in check for lagging sender 2024-12-31 11:58:03 -05:00