diff --git a/src/modules/module-rtp-sink.c b/src/modules/module-rtp-sink.c index 241e1e01e..b0c622d1a 100644 --- a/src/modules/module-rtp-sink.c +++ b/src/modules/module-rtp-sink.c @@ -67,6 +67,8 @@ * - `net.mtu = `: MTU to use, default 1280 * - `net.ttl = `: TTL to use, default 1 * - `net.loop = `: loopback multicast, default false + * - `sess.min-ptime = `: minimum packet time in milliseconds, default 2 + * - `sess.max-ptime = `: maximum packet time in milliseconds, default 20 * - `sess.name = `: a session name * - `stream.props = {}`: properties to be passed to the stream * @@ -101,6 +103,8 @@ * #net.mtu = 1280 * #net.ttl = 1 * #net.loop = false + * #sess.min-ptime = 2 + * #sess.max-ptime = 20 * #sess.name = "PipeWire RTP stream" * #audio.format = "S16BE" * #audio.rate = 48000 @@ -155,6 +159,8 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); "net.ttl= " \ "net.loop= " \ "sess.name= " \ + "sess.min-ptime= " \ + "sess.max-ptime= " \ "audio.format= " \ "audio.rate= " \ "audio.channels= "\ @@ -216,6 +222,7 @@ struct impl { bool mcast_loop; uint32_t min_ptime; uint32_t max_ptime; + uint32_t pbytes; struct sockaddr_storage src_addr; socklen_t src_len; @@ -276,7 +283,7 @@ static void flush_packets(struct impl *impl) avail = spa_ringbuffer_get_read_index(&impl->ring, &index); - tosend = SPA_ROUND_DOWN(impl->mtu, impl->frame_size); + tosend = impl->pbytes; if (avail < tosend) return; @@ -482,7 +489,7 @@ static int setup_stream(struct impl *impl) if (pw_properties_get(props, PW_KEY_NODE_LATENCY) == NULL) { pw_properties_setf(props, PW_KEY_NODE_LATENCY, - "%d/%d", impl->mtu / impl->frame_size, + "%d/%d", impl->pbytes / impl->frame_size, impl->info.rate); } pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%d", impl->info.rate); @@ -593,7 +600,7 @@ static void send_sap(struct impl *impl, bool bye) impl->port, impl->payload, impl->payload, impl->format_info->mime, impl->info.rate, impl->info.channels, - (impl->mtu / impl->frame_size) * 1000 / impl->info.rate); + (impl->pbytes / impl->frame_size) * 1000 / impl->info.rate); iov[3].iov_base = buffer; iov[3].iov_len = strlen(buffer); @@ -786,7 +793,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) struct impl *impl; struct pw_properties *props = NULL, *stream_props = NULL; uint32_t id = pw_global_get_id(pw_impl_module_get_global(module)); - uint32_t pid = getpid(), port; + uint32_t pid = getpid(), port, min_bytes, max_bytes; char addr[64]; const char *str; int res = 0; @@ -903,6 +910,12 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) impl->min_ptime = pw_properties_get_uint32(props, "sess.min-ptime", DEFAULT_MIN_PTIME); impl->max_ptime = pw_properties_get_uint32(props, "sess.max-ptime", DEFAULT_MAX_PTIME); + min_bytes = (impl->min_ptime * impl->info.rate / 1000) * impl->frame_size; + max_bytes = (impl->max_ptime * impl->info.rate / 1000) * impl->frame_size; + + impl->pbytes = SPA_ROUND_DOWN(impl->mtu, impl->frame_size); + impl->pbytes = SPA_CLAMP(impl->pbytes, min_bytes, max_bytes); + if ((str = pw_properties_get(props, "sess.name")) == NULL) pw_properties_setf(props, "sess.name", "PipeWire RTP Stream on %s", pw_get_host_name()); @@ -917,6 +930,8 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) pw_properties_setf(stream_props, "rtp.destination.port", "%u", impl->port); pw_properties_setf(stream_props, "rtp.mtu", "%u", impl->mtu); pw_properties_setf(stream_props, "rtp.ttl", "%u", impl->ttl); + pw_properties_setf(stream_props, "rtp.ptime", "%u", + (impl->pbytes / impl->frame_size) * 1000 / impl->info.rate); impl->core = pw_context_get_object(impl->module_context, PW_TYPE_INTERFACE_Core); if (impl->core == NULL) {