Commit graph

73 commits

Author SHA1 Message Date
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
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
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
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
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
45eee02a99 module-rtp: Account for in-flight samples in RTP receive
When not using PTP as the driver, it is possible that packet receive and
the process() callback are out of sync, meaning that the target buffer
fill level might be off by upto one ptime's worth of samples
occasionally. This would make the DLL hunt for the target rate, and
cause a constantly varying delay.

Accounting for the delta between the packet receive time and the
process() time allows us to eliminate this jitter, resulting in much
more consistent rate matching.
2024-11-27 11:48:50 +00:00
Wim Taymans
804df3389a modules: use pw_stream_set_rate() when we can 2024-11-22 09:49:27 +01:00
Wim Taymans
44340fde05 module-rtp: allocate receive buffer based on MTU
Use the MTU to allocate the receive buffer instead of using a hardcoded
size.

Fixes #4394
2024-11-11 12:03:32 +01:00
Wim Taymans
a53bc035c0 module-rtp: calculate payload_size based on MTU
The actual payload size depends on the MTU but should not include the
IP/UDP and RTP headers.

Fixes #4396
2024-11-11 11:49:20 +01:00
Wim Taymans
404817592b module-rtp: don't confuse time and samples
Round down the target_buffer size to a psamples multiple. Don't try to
mix time and sample units for this.

Fixes #4327
2024-09-30 10:44:51 +02:00
Wim Taymans
e3a7035e8f spa: make helper to init spa_audio_info_raw from dict
Make a function that can initialize raw audio info from a dict and fill
in the defaults. We can use this in many of the modules when the audio
format is parsed.
2024-09-18 15:48:27 +02:00
Wim Taymans
e2991f6398 json: add helper function to parse channel positions
Use the helper instead of duplicating the same code.

Also add some helpers to parse a json array of uint32_t

Move some functions to convert between type name and id.
2024-09-18 09:54:34 +02:00
Wim Taymans
cd81b5f39a spa: add spa_json_begin_array/object and relaxed versions
Add spa_json_begin_array/object to replace
spa_json_init+spa_json_begin_array/object

This function is better because it does not waste a useless spa_json
structure as an iterator. The relaxed versions also error out when the
container is mismatched because parsing a mismatched container is not
going to give any results anyway.
2024-09-16 09:50:33 +02:00
Arun Raghavan
9f643fec7e module-rtp: Allow aes67 send with a non PTP clock
Our current AES67 sender setup requires that that PTP driver drive the
entire graph. This adds support for allowing the AES67 RTP sink to be
driven by an arbitrary driver, while still using the PTP driver for
sending data on the network.

When aes67.driver-group is specified a pw_filter is created with no
ports, node.always-process = true and node.group set to the
aes67.driver-group. When set to PTP, this gives us process callbacks at
the PTP rate which we use to get the current PTP time in the RTP sender
by interpolating the clock snapshots from the pw-filter.

Implementation ideas from Wim Taymans. Co-authored with Sanchayan Maity.

For a detailed reference, refer the following papers by Fons Adriaensen.
- Using a DLL to filter time
  (https://kokkinizita.linuxaudio.org/papers/usingdll.pdf)
- Controlling adaptive resampling
  (http://kokkinizita.linuxaudio.org/papers/adapt-resamp.pdf)
2024-08-27 01:38:10 +00:00
Wim Taymans
d9e7a10b0d modules: accept and produce UMP only 2024-07-30 09:38:40 +02:00
Wim Taymans
8a62563d5b module-rtp: fix ptime and target_buffer checks
target_buffer is in samples and ptime in msec so we can't really compare
them. Use psamples instead, which is ptime but then as samples.

See #4095
2024-07-19 13:17:51 +02:00
Barnabás Pőcze
7732d0e3e5 pipewire: module-raop-sink: use uint32_t for sample rate
32 bits are enough, and additionally this also fixes an incorrect
format string, which caused the default `audio.rate` to be
incorrectly set on some platforms, such as 32-bit arm ones.

Fixes #4080
2024-06-27 09:46:45 +02:00
Christian Glombek
4067b3a985 module-rtp/stream: Fix setting marker_on_first prop for RAOP 2024-06-27 06:04:56 +02:00
Wim Taymans
51bf143a77 module-rtp: fix fmodf usage 2024-06-18 16:01:41 +02:00
Wim Taymans
a76d262db6 modules: fix compilation 2024-06-18 15:47:02 +02:00
Wim Taymans
1ae4374ccf Fix compilation with -Werror=float-conversion
Better make the conversions explicit so that we don't get any surprises.

Fixes #4065
2024-06-18 12:17:56 +02:00
Wim Taymans
c3d4abd7f1 modules: use acquire/release loop
Expose the acquire_loop/release_loop functions and use them in the
modules.

Make sure the nodes created from the module use the same data loop as
the module. We need to ensure this because otherwise, the nodes might
be scheduled on different data loops and the invoke or timer logic will
fail.
2024-04-22 16:19:02 +02:00
Jonas Holmberg
09088b376f rtp_stream: Use the log topic of the module
Set log topic to the topic of the module linked with stream instead of
logging with "default" topic.
2024-04-17 07:13:53 +00:00
Jonas Holmberg
64d75b6b2e module-rtp-sink: Send all remaining packets when stopping
Don't close rtp_fd until all packets have been sent by the timer, if
the timer is running when the stream is stopped.
2024-04-16 07:50:33 +00:00
Wim Taymans
4ffd74ef46 module-rtp: handle state change errors better
Make a new function to set the rtp stream in the error state.

When we fail to start the stream, set the error state. Otherwise (like
when we try to use an invalid interface name) the socket create will
fail but the stream will still try to send data to the invalid socket.
2024-03-25 12:22:11 +01:00
Wim Taymans
5082e9f458 module-rtp: only stop timer when it was running 2024-02-15 17:48:58 +01:00
Jonas Holmberg
4715fa1775 module-rtp: Add source/destination.ip to props
Make it possible to change source.ip in module-rtp-source and
destination.ip in module-rtp-sink.
2024-02-08 09:30:58 +00:00
Arun Raghavan
0c37adb665 module-rtp: Add some sender latency validation
Just a sanity check on config.
2024-01-30 21:26:14 +00:00
Wim Taymans
78055736a2 module-rtp: add packet timer
When multiple packets need to be flushed (because sess.latency is set
and larger than ptime) use a timer to space the packets uniformly in
the current quantum to avoid bursts.

See !1873
2024-01-30 10:06:27 +01:00
Wim Taymans
c37f9f9cf0 module-rtp: use sess.latency.msec also for sender
Use the sess.latency.msec also for the sender and use it to control the
NODE_LATENCY. Make it a float to be in line with the other time values.
Set is to a default of ptime, which was what it used to be.

This makes it possible to set the ptime to a smaller value than the
sess.latency.msec so that we send out multiple packets per quantum.
This will result in some bursty output for now but with a timer that can
be improved later.

Update the docs a little, mention the new rtp.ptime and rtp.frametime.
2024-01-25 15:49:41 +01:00
Wim Taymans
ec825086f1 module-rtp: use helpers to convert between samples and msec
And make sure we don't do any useless float to double conversions.
2024-01-25 15:30:04 +01:00
Wim Taymans
9458367a50 module-rtp: Fix framecount vs ptime check
We should use framecount instead of impl->psamples.
2024-01-25 15:12:25 +01:00
Wim Taymans
9a5609de2b modules: move some spa_debug_mem to the log
Instead of dumping to stderr, write it to the log file.
2024-01-11 17:49:50 +01:00
Dmitry Sharshakov
065e819f18 TODO: module-rtp: buffering for sender
This should be done to match packet size requirements (e.g. 1 ms) while allowing user's software to run at higher buffer size to not stutter.

This will require scheduling multiple rtp_audio_flush_packets calls per one rtp_audio_process_capture call
2023-12-20 09:35:22 +00:00
Dmitry Sharshakov
873e6119b8 module-rtp: handle framecount attribute 2023-12-20 09:35:22 +00:00
Dmitry Sharshakov
533161a766 module-rtp: add framecount to the SDP
Required for RAVENNA hardware.

Co-authored-by: Dewi Seignard <dewiweb@gmail.com>
2023-12-20 09:35:22 +00:00
Wim Taymans
5e750f6fb8 modules: place floats in properties in JSON format
Using %f will result in a locale dependent format and might not parse
with JSON parsers or even our own spa_atof() function.
2023-12-14 11:50:30 +01:00
Arun Raghavan
63bb128948 rtp-stream: Set rtp.ptime on senders not receivers
The pw_stream direction is inverted from what we want (input => sender).
2023-11-23 01:28:20 -05:00
Christian Glombek
cbac8c9040 module-rtp/stream: Add support for RAOP 2023-10-09 10:52:25 +02:00
Christian Glombek
8704aaa044 module-rtp/stream: Add getter for pw_stream state 2023-10-09 10:52:25 +02:00