From 8e5b9da177c8666984b7b61d8a47d984670133b1 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 6 Mar 2023 10:46:21 +0100 Subject: [PATCH] module-rtp: fix direct timestamps fix some other properties. --- src/modules/module-rtp-sap.c | 7 ++++--- src/modules/module-rtp-session.c | 25 ++++++++++++++++++++----- src/modules/module-rtp-sink.c | 9 +++++++++ src/modules/module-rtp-source.c | 9 +++++++++ src/modules/module-rtp/audio.c | 4 ++-- src/modules/module-rtp/stream.c | 8 ++------ 6 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/modules/module-rtp-sap.c b/src/modules/module-rtp-sap.c index 1e4eb18d8..90e60c9db 100644 --- a/src/modules/module-rtp-sap.c +++ b/src/modules/module-rtp-sap.c @@ -648,8 +648,9 @@ static struct session *session_new_announce(struct impl *impl, struct node *node sdp->ntp = (uint32_t) time(NULL) + 2208988800U; sess->props = props; - if ((str = pw_properties_get(props, "sess.name")) != NULL) - sdp->session_name = strdup(str); + if ((str = pw_properties_get(props, "sess.name")) == NULL) + str = pw_get_host_name(); + sdp->session_name = strdup(str); if ((str = pw_properties_get(props, "rtp.destination.port")) == NULL) goto error_free; @@ -763,7 +764,7 @@ static int session_load_source(struct session *session, struct pw_properties *pr return -EINVAL; } if ((str = pw_properties_get(props, "rtp.ts-offset")) != NULL) - pw_properties_set(props, "sess.ts-offset", str); + fprintf(f, "\"sess.ts-offset\" = %s, ", str); fprintf(f, " stream.props = {"); pw_properties_serialize_dict(f, &props->dict, 0); diff --git a/src/modules/module-rtp-session.c b/src/modules/module-rtp-session.c index 33675d993..254c842e7 100644 --- a/src/modules/module-rtp-session.c +++ b/src/modules/module-rtp-session.c @@ -64,7 +64,7 @@ * - `sess.name = `: a session name * - `sess.ts-offset = `: an offset to apply to the timestamp, default -1 = random offset * - `sess.ts-refclk = `: the name of a reference clock - * - `sess.media = `: the media type audio|midi, default audio + * - `sess.media = `: the media type audio|midi, default midi * - `stream.props = {}`: properties to be passed to the stream * * ## General options @@ -487,6 +487,7 @@ static struct session *make_session(struct impl *impl, struct pw_properties *pro { struct session *sess; const char *str; + struct pw_properties *copy; sess = calloc(1, sizeof(struct session)); if (sess == NULL) @@ -507,15 +508,29 @@ static struct session *make_session(struct impl *impl, struct pw_properties *pro pw_properties_setf(props, "rtp.sender-ssrc", "%u", sess->ssrc); pw_properties_set(props, "rtp.session", sess->name); + copy = pw_properties_copy(props); + + if (pw_properties_get(props, PW_KEY_MEDIA_CLASS) == NULL) { + const char *media = NULL; + + str = pw_properties_get(props, "sess.media"); + if (spa_streq(str, "midi")) + media = "Midi"; + else if (spa_streq(str, "audio")) + media = "Audio"; + + if (media != NULL) { + pw_properties_setf(copy, PW_KEY_MEDIA_CLASS, "%s/Sink", media); + pw_properties_setf(props, PW_KEY_MEDIA_CLASS, "%s/Source", media); + } + } sess->send = rtp_stream_new(impl->core, - PW_DIRECTION_INPUT, pw_properties_copy(props), + PW_DIRECTION_INPUT, copy, &send_stream_events, sess); sess->recv = rtp_stream_new(impl->core, - PW_DIRECTION_OUTPUT, pw_properties_copy(props), + PW_DIRECTION_OUTPUT, props, &recv_stream_events, sess); - pw_properties_free(props); - return sess; error: pw_properties_free(props); diff --git a/src/modules/module-rtp-sink.c b/src/modules/module-rtp-sink.c index baaafdb3a..b409e243e 100644 --- a/src/modules/module-rtp-sink.c +++ b/src/modules/module-rtp-sink.c @@ -111,6 +111,8 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); #define DEFAULT_LOOP false #define DEFAULT_DSCP 34 /* Default to AES-67 AF41 (34) */ +#define DEFAULT_TS_OFFSET -1 + #define USAGE "source.ip= " \ "destination.ip= " \ "destination.port= " \ @@ -395,6 +397,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) struct pw_properties *props = NULL, *stream_props = NULL; char addr[64]; const char *str, *sess_name; + int64_t ts_offset; int res = 0; PW_LOG_TOPIC_INIT(mod_topic); @@ -460,6 +463,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, "sess.min-ptime"); copy_props(impl, props, "sess.max-ptime"); copy_props(impl, props, "sess.latency.msec"); + copy_props(impl, props, "sess.ts-refclk"); str = pw_properties_get(props, "local.ifname"); impl->ifname = str ? strdup(str) : NULL; @@ -484,6 +488,11 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) impl->mcast_loop = pw_properties_get_bool(props, "net.loop", DEFAULT_LOOP); impl->dscp = pw_properties_get_uint32(props, "net.dscp", DEFAULT_DSCP); + ts_offset = pw_properties_get_int64(props, "sess.ts-offset", DEFAULT_TS_OFFSET); + if (ts_offset == -1) + ts_offset = pw_rand32(); + pw_properties_setf(stream_props, "rtp.sender-ts-offset", "%u", (uint32_t)ts_offset); + get_ip(&impl->src_addr, addr, sizeof(addr)); pw_properties_set(stream_props, "rtp.source.ip", addr); get_ip(&impl->dst_addr, addr, sizeof(addr)); diff --git a/src/modules/module-rtp-source.c b/src/modules/module-rtp-source.c index a084d06c8..61a45f558 100644 --- a/src/modules/module-rtp-source.c +++ b/src/modules/module-rtp-source.c @@ -99,6 +99,8 @@ PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); #define DEFAULT_CLEANUP_SEC 60 #define DEFAULT_SOURCE_IP "224.0.0.56" +#define DEFAULT_TS_OFFSET -1 + #define USAGE "local.ifname= " \ "source.ip= " \ "source.port= " \ @@ -427,6 +429,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) const char *str, *sess_name; struct timespec value, interval; struct pw_properties *props, *stream_props; + int64_t ts_offset; int res = 0; PW_LOG_TOPIC_INIT(mod_topic); @@ -483,6 +486,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, "sess.min-ptime"); copy_props(impl, props, "sess.max-ptime"); copy_props(impl, props, "sess.latency.msec"); + copy_props(impl, props, "sess.ts-direct"); str = pw_properties_get(props, "local.ifname"); impl->ifname = str ? strdup(str) : NULL; @@ -499,6 +503,11 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) goto out; } + ts_offset = pw_properties_get_int64(props, "sess.ts-offset", DEFAULT_TS_OFFSET); + if (ts_offset == -1) + ts_offset = pw_rand32(); + pw_properties_setf(stream_props, "rtp.receiver-ts-offset", "%u", (uint32_t)ts_offset); + impl->always_process = pw_properties_get_bool(stream_props, PW_KEY_NODE_ALWAYS_PROCESS, true); diff --git a/src/modules/module-rtp/audio.c b/src/modules/module-rtp/audio.c index e1855f504..2fd5f79bc 100644 --- a/src/modules/module-rtp/audio.c +++ b/src/modules/module-rtp/audio.c @@ -141,9 +141,9 @@ static int receive_rtp_audio(struct impl *impl, uint8_t *buffer, ssize_t len) write = timestamp + impl->target_buffer; if (!impl->have_sync) { - pw_log_info("sync to timestamp:%u seq:%u ts_offset:%u SSRC:%u direct:%d", + pw_log_info("sync to timestamp:%u seq:%u ts_offset:%u SSRC:%u target:%u direct:%u", write, impl->seq-1, impl->ts_offset, impl->ssrc, - impl->direct_timestamp); + impl->target_buffer, impl->direct_timestamp); /* we read from timestamp, keeping target_buffer of data * in the ringbuffer. */ diff --git a/src/modules/module-rtp/stream.c b/src/modules/module-rtp/stream.c index b26b73ac5..1e32e00a4 100644 --- a/src/modules/module-rtp/stream.c +++ b/src/modules/module-rtp/stream.c @@ -250,7 +250,7 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core, const struct rtp_stream_events *events, void *data) { struct impl *impl; - const char *str, *media_class; + const char *str; uint8_t buffer[1024]; struct spa_pod_builder b; uint32_t n_params, min_samples, max_samples; @@ -301,7 +301,6 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core, } impl->stride = impl->format_info->size * impl->info.info.raw.channels; impl->rate = impl->info.info.raw.rate; - media_class = direction == PW_DIRECTION_INPUT ? "Audio/Sink" : "Audio/Source"; break; case SPA_MEDIA_TYPE_application: impl->format_info = find_audio_format_info(&impl->info); @@ -314,7 +313,6 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core, impl->rate = pw_properties_get_uint32(props, "midi.rate", 10000); if (impl->rate == 0) impl->rate = 10000; - media_class = direction == PW_DIRECTION_INPUT ? "Midi/Sink" : "Midi/Source"; break; default: spa_assert_not_reached(); @@ -323,8 +321,6 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core, pw_properties_setf(props, "rtp.mime", "%s", impl->format_info->mime); - if (pw_properties_get(props, PW_KEY_MEDIA_CLASS) == NULL) - pw_properties_set(props, PW_KEY_MEDIA_CLASS, media_class); if (pw_properties_get(props, PW_KEY_NODE_VIRTUAL) == NULL) pw_properties_set(props, PW_KEY_NODE_VIRTUAL, "true"); if (pw_properties_get(props, PW_KEY_NODE_NETWORK) == NULL) @@ -337,7 +333,7 @@ struct rtp_stream *rtp_stream_new(struct pw_core *core, impl->ts_offset = pw_properties_get_uint32(props, "rtp.sender-ts-offset", pw_rand32()); } else { impl->have_ssrc = pw_properties_fetch_uint32(props, "rtp.receiver-ssrc", &impl->ssrc); - if (!pw_properties_fetch_uint32(props, "rtp.receiver-ts-offset", &impl->ts_offset)) + if (pw_properties_fetch_uint32(props, "rtp.receiver-ts-offset", &impl->ts_offset) < 0) impl->direct_timestamp = false; }