From 39d6e40abd27c9a1f000c67906820c5e2ea89628 Mon Sep 17 00:00:00 2001 From: Sebastian Jaeckel Date: Tue, 16 May 2023 15:44:32 +0200 Subject: [PATCH] rtp-sap,AES67: reorder sdp records to be compatible with Dante/AES67 devices A software called `Dante Controller` is needed to configure Dante devices (which also support AES67). This software is picky about the order in which SDP records are received and parsed. Changing the order or adding new records in between leads to faulty display of our stream within `Dante Controller` (missing channel display etc.) and the user is then unable to connect any Dante device to the AES67 stream. --- src/modules/module-rtp-sap.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/modules/module-rtp-sap.c b/src/modules/module-rtp-sap.c index 70db42e55..ac5d731ae 100644 --- a/src/modules/module-rtp-sap.c +++ b/src/modules/module-rtp-sap.c @@ -520,35 +520,33 @@ static int send_sap(struct impl *impl, struct session *sess, bool bye) snprintf(dst_ttl, sizeof(dst_ttl), "/%d", sdp->ttl); spa_strbuf_init(&buf, buffer, sizeof(buffer)); + /* Don't add any sdp records in between this definition or change the order + it will break compatibility with Dante/AES67 devices. Add new records to + the end. */ spa_strbuf_append(&buf, "v=0\n" "o=%s %u 0 IN %s %s\n" "s=%s\n" "c=IN %s %s%s\n" "t=%u 0\n" - "a=recvonly\n" - "a=tool:PipeWire %s\n" - "a=type:broadcast\n", + "m=%s %u RTP/AVP %i\n", user_name, sdp->ntp, src_ip4 ? "IP4" : "IP6", src_addr, sdp->session_name, dst_ip4 ? "IP4" : "IP6", dst_addr, dst_ttl, sdp->ntp, - pw_get_library_version()); - spa_strbuf_append(&buf, - "m=%s %u RTP/AVP %i\n", - sdp->media_type, - sdp->dst_port, sdp->payload); + sdp->media_type, sdp->dst_port, sdp->payload); if (sdp->channels) { - spa_strbuf_append(&buf, - "a=rtpmap:%i %s/%u/%u\n", - sdp->payload, sdp->mime_type, - sdp->rate, sdp->channels); if (sdp->channelmap[0] != 0) { spa_strbuf_append(&buf, "i=%d channels: %s\n", sdp->channels, sdp->channelmap); } + spa_strbuf_append(&buf, + "a=recvonly\n" + "a=rtpmap:%i %s/%u/%u\n", + sdp->payload, sdp->mime_type, + sdp->rate, sdp->channels); } else { spa_strbuf_append(&buf, "a=rtpmap:%i %s/%u\n", @@ -569,6 +567,11 @@ static int send_sap(struct impl *impl, struct session *sess, bool bye) spa_strbuf_append(&buf, "a=mediaclk:sender\n"); } + spa_strbuf_append(&buf, + "a=tool:PipeWire %s\n" + "a=type:broadcast\n", + pw_get_library_version()); + pw_log_debug("sending SAP for %u %s", sess->node->id, buffer); iov[3].iov_base = buffer;