From e046eecb96c17521924465fc7c89d00f3c2d801c Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 28 Aug 2025 14:19:10 -0400 Subject: [PATCH] MT#63317 print extensions from list Change-Id: Iec3824adb461264ea67f937258ba592f2fd82209 --- daemon/media_socket.c | 77 +++++++++++++++++++++++++++++++++- t/auto-daemon-tests-rtp-ext.pl | 16 +++---- 2 files changed, 84 insertions(+), 9 deletions(-) diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 64edcbfbf..a48e04cc9 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -2078,6 +2078,75 @@ const struct rtpext_printer rtpext_printer_copy = { }; +static size_t rtpext_printer_extmap_length(const struct media_packet *mp) { + if (mp->rtcp) + return 0; + if (!mp->extmap.length) + return 0; + + __auto_type media = mp->media_out; + if (!media) + return 0; + + size_t ret = media->extmap_ops->length(mp); + + // pad to 32 bits + ret = (ret + 3) & ~3L; + + return ret; +} +static size_t rtpext_printer_extmap_print(struct rtp_header *rh, void *dst, const struct media_packet *mp) { + rh->v_p_x_cc &= ~0x10; + + if (mp->rtcp) + return 0; + if (!mp->extmap.length) + return 0; + + __auto_type media = mp->media_out; + if (!media) + return 0; + + void *header = dst; + dst += 4; // fixed size header + void *first = dst; + + for (__auto_type l = mp->extmap.head; l; l = l->next) { + __auto_type ext = l->data; + size_t len = media->extmap_ops->print(dst, ext); + dst += len; + } + + if (dst == first) + return 0; // nothing was printed + + // header + media->extmap_ops->header(header); + rh->v_p_x_cc |= 0x10; + + // total length + size_t size = dst - header; + + // round up to 32 bits + size_t padded = (size + 3) & ~3L; + + // null out padding + memset(dst, 0, padded - size); + + // put length header + uint16_t *lp = header + 2; + *lp = htons(padded / 4 - 1); + + return padded; +} + +static const struct rtpext_printer rtpext_printer_extmap = { + .length = rtpext_printer_extmap_length, + .print = rtpext_printer_extmap_print, + .may_copy = false, +}; + + static bool extmap_short_is_valid(const struct rtp_extension_data *ext) { // valid ranges for short form? @@ -2103,6 +2172,9 @@ size_t extmap_length_short(const struct media_packet *mp) { ret += ext->content.len; } + if (ret == 4) + return 0; // nothing left + return ret; } @@ -2164,7 +2236,10 @@ static void __determine_rtpext_handler(struct call_media *in, struct call_media if (!sh || !out) return; - sh->rtpext = &rtpext_printer_copy; + if (in->extmap.length || out->extmap.length) + sh->rtpext = &rtpext_printer_extmap; + else + sh->rtpext = &rtpext_printer_copy; } diff --git a/t/auto-daemon-tests-rtp-ext.pl b/t/auto-daemon-tests-rtp-ext.pl index 00509ae0f..83e5b8b29 100755 --- a/t/auto-daemon-tests-rtp-ext.pl +++ b/t/auto-daemon-tests-rtp-ext.pl @@ -504,10 +504,10 @@ a=sendrecv a=rtcp:PORT SDP -snd($sock_a, $port_b, rtp( 8, 1000, 3000+160*0, 0x1234, "\x39" . ("\x29" x 158) . "\x74", [[1, "foo"], [4, "argh"], [3, "yikes"]])); -rcv($sock_b, $port_a, rtpm(8, 1000, 3000+160*0, 0x1234, "\x39" . ("\x29" x 158) . "\x74", [[1, "foo"], [4, "argh"], [3, "yikes"]])); -snd($sock_b, $port_a, rtp( 8, 8000, 7000+160*0, 0x6543, "\x39" . ("\x29" x 158) . "\x74", [[2, "blah"], [4, "argh"], [3, "yikes"]])); -rcv($sock_a, $port_b, rtpm(8, 8000, 7000+160*0, 0x6543, "\x39" . ("\x29" x 158) . "\x74", [[2, "blah"], [4, "argh"], [3, "yikes"]])); +snd($sock_a, $port_b, rtp( 8, 1000, 3000+160*0, 0x1234, "\x39" . ("\x29" x 158) . "\x74", [[1, "foo"], [2, "blah"], [4, "argh"], [3, "yikes"]])); +rcv($sock_b, $port_a, rtpm(8, 1000, 3000+160*0, 0x1234, "\x39" . ("\x29" x 158) . "\x74", [[1, "foo"], [2, "blah"], [4, "argh"], [3, "yikes"]])); +snd($sock_b, $port_a, rtp( 8, 8000, 7000+160*0, 0x6543, "\x39" . ("\x29" x 158) . "\x74", [[1, "foo"], [2, "blah"], [4, "argh"], [3, "yikes"]])); +rcv($sock_a, $port_b, rtpm(8, 8000, 7000+160*0, 0x6543, "\x39" . ("\x29" x 158) . "\x74", [[1, "foo"], [2, "blah"], [4, "argh"], [3, "yikes"]])); @@ -578,10 +578,10 @@ a=sendrecv a=rtcp:PORT SDP -snd($sock_a, $port_b, rtp( 8, 1000, 3000+160*0, 0x1234, "\x39" . ("\x29" x 158) . "\x74", [[1, "foo"], [4, "argh"], [3, "yikes"]])); -rcv($sock_b, $port_a, rtpm(0, 1000, 3000+160*0, 0x1234, "\x13" . ("\x03" x 158) . "\x5a", [[1, "foo"], [4, "argh"], [3, "yikes"]])); -snd($sock_b, $port_a, rtp( 0, 8000, 7000+160*0, 0x6543, "\x39" . ("\x29" x 158) . "\x74", [[2, "blah"], [4, "argh"], [3, "yikes"]])); -rcv($sock_a, $port_b, rtpm(8, 8000, 7000+160*0, 0x6543, "\x10" . ("\x00" x 158) . "\x50", [[2, "blah"], [4, "argh"], [3, "yikes"]])); +snd($sock_a, $port_b, rtp( 8, 1000, 3000+160*0, 0x1234, "\x39" . ("\x29" x 158) . "\x74", [[1, "foo"], [2, "blah"], [4, "argh"], [3, "yikes"]])); +rcv($sock_b, $port_a, rtpm(0, 1000, 3000+160*0, 0x1234, "\x13" . ("\x03" x 158) . "\x5a", [[1, "foo"], [2, "blah"], [3, "yikes"]])); +snd($sock_b, $port_a, rtp( 0, 8000, 7000+160*0, 0x6543, "\x39" . ("\x29" x 158) . "\x74", [[1, "foo"], [2, "blah"], [4, "argh"], [3, "yikes"]])); +rcv($sock_a, $port_b, rtpm(8, 8000, 7000+160*0, 0x6543, "\x10" . ("\x00" x 158) . "\x50", [[1, "foo"], [2, "blah"]]));