From 64d3c7646c32e0c568781eb6900c8377260c9576 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 30 Jul 2025 11:17:42 -0400 Subject: [PATCH] MT#63317 parse out RTP header extensions Stub function for now. Change-Id: I7ad2a203f42fb118e50273a57772cac4fbd1738f --- daemon/media_socket.c | 23 ++++++++++++- include/media_socket.h | 1 + lib/rtplib.c | 74 ++++++++++++++++++++++++++++++++++++++++++ lib/rtplib.h | 7 ++++ 4 files changed, 104 insertions(+), 1 deletion(-) diff --git a/daemon/media_socket.c b/daemon/media_socket.c index b1fba6f51..fff1916f0 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -2304,7 +2304,7 @@ static void media_packet_parse(struct packet_handler_ctx *phc) { return; if (!phc->rtcp) { - phc->mp.rtp = rtp_payload(&phc->mp.payload, &phc->s, NULL); + phc->mp.rtp = rtp_payload(&phc->mp.payload, &phc->s, &phc->mp.extensions); if (G_LIKELY(phc->mp.rtp)) { // check the payload type // XXX redundant between SSRC handling and codec_handler stuff -> combine @@ -2346,6 +2346,24 @@ static void media_packet_rtcp_mux(struct packet_handler_ctx *phc, struct sink_ha } +static void media_packet_rtp_extension(struct packet_handler_ctx *phc, unsigned int id, const str *data) { + __auto_type ext = phc->mp.media->extmap_lookup(phc->mp.media, id); + if (!ext) + return; + + // stub +} + +static void media_packet_rtp_extensions(struct packet_handler_ctx *phc) { + if (!phc->mp.media->extmap.length) + return; + if (!phc->mp.extensions.len) + return; + + rtp_rfc8285_iterate(&phc->mp.extensions, media_packet_rtp_extension, phc); +} + + // sets ssrc_in and tracks stats static void media_packet_rtp_in(struct packet_handler_ctx *phc) { if (G_UNLIKELY(!phc->mp.media)) @@ -2381,6 +2399,8 @@ static void media_packet_rtp_in(struct packet_handler_ctx *phc) { atomic64_add(&rtp_s->bytes, phc->s.len); g_atomic_pointer_set(&phc->mp.stream->rtp_stats_cache, rtp_s); } + + media_packet_rtp_extensions(phc); } else if (phc->rtcp) { unkern = __stream_ssrc_in(phc->in_srtp, phc->mp.rtcp->ssrc, &phc->mp.ssrc_in, @@ -2775,6 +2795,7 @@ void media_packet_copy(struct media_packet *dst, const struct media_packet *src) dst->rtcp = __g_memdup(src->rtcp, sizeof(*src->rtcp)); dst->payload = STR_NULL; dst->raw = STR_NULL; + dst->extensions = STR_NULL; } void media_packet_release(struct media_packet *mp) { if (mp->sfd) diff --git a/include/media_socket.h b/include/media_socket.h index bd8808022..8a2d20de1 100644 --- a/include/media_socket.h +++ b/include/media_socket.h @@ -281,6 +281,7 @@ struct media_packet { struct rtcp_packet *rtcp; struct ssrc_entry_call *ssrc_in, *ssrc_out; // SSRC contexts from in_srtp and out_srtp str payload; + str extensions; codec_packet_q packets_out; int ptime; // returned from decoding diff --git a/lib/rtplib.c b/lib/rtplib.c index 3f506d15c..72003e53e 100644 --- a/lib/rtplib.c +++ b/lib/rtplib.c @@ -11,6 +11,17 @@ struct rtp_exthdr { uint16_t length; } __attribute__ ((packed)); +struct rtp_rfc8285_hdr { + uint8_t be; + uint8_t de; + uint16_t length; +} __attribute__ ((packed)); + +struct rtp_rfc8285_item { + uint8_t id; + uint8_t length; +} __attribute__ ((packed)); + @@ -55,8 +66,71 @@ const struct rtp_payload_type rfc_rtp_payload_types[] = const int num_rfc_rtp_payload_types = G_N_ELEMENTS(rfc_rtp_payload_types); +static void rtp_rfc8285_iterate_short(str s, const struct rtp_rfc8285_hdr *hdr, + rtp_rfc8285_handler cb, struct packet_handler_ctx *arg) +{ + str_shift(&s, sizeof(*hdr)); + + while (s.len) { + uint8_t id_len = s.s[0]; + if (id_len == '\0') { + // padding + str_shift(&s, 1); + continue; + } + uint8_t id = id_len >> 4; + uint8_t len = (id_len & 0xf) + 1; + str_shift(&s, 1); + + if (s.len < len) + return; + + cb(arg, id, &STR_LEN(s.s, len)); + + str_shift(&s, len); + } +} + +static void rtp_rfc8285_iterate_long(str s, const struct rtp_rfc8285_hdr *hdr, + rtp_rfc8285_handler cb, struct packet_handler_ctx *arg) +{ + str_shift(&s, sizeof(*hdr)); + + struct rtp_rfc8285_item *item; + + while (s.len >= sizeof(*item)) { + if (s.s[0] == '\0') { + // padding + str_shift(&s, 1); + continue; + } + + item = (struct rtp_rfc8285_item *) s.s; + + str_shift(&s, sizeof(*item)); + + if (s.len < item->length) + return; + cb(arg, item->id, &STR_LEN(s.s, item->length)); + str_shift(&s, item->length); + } +} + +void rtp_rfc8285_iterate(const str *extensions, rtp_rfc8285_handler cb, struct packet_handler_ctx *arg) { + const struct rtp_rfc8285_hdr *hdr; + + if (extensions->len < sizeof(*hdr)) + return; + + hdr = (struct rtp_rfc8285_hdr *) extensions->s; + + if (hdr->be == 0xbe && hdr->de == 0xde) + rtp_rfc8285_iterate_short(*extensions, hdr, cb, arg); + else if (hdr->be == 0x10 && (hdr->de & 0xf0) == 0x00) + rtp_rfc8285_iterate_long(*extensions, hdr, cb, arg); +} struct rtp_header *rtp_payload(str *p, const str *s, str *exts) { diff --git a/lib/rtplib.h b/lib/rtplib.h index 8d9e9a4b8..c554771bb 100644 --- a/lib/rtplib.h +++ b/lib/rtplib.h @@ -131,6 +131,13 @@ __attribute__((nonnull(2))) struct rtp_header *rtp_payload(str *p, const str *s, str *ext); __attribute__((nonnull(2))) bool rtp_padding(const struct rtp_header *header, str *payload); + +struct packet_handler_ctx; + +typedef void (*rtp_rfc8285_handler)(struct packet_handler_ctx *, unsigned int, const str *); +void rtp_rfc8285_iterate(const str *, rtp_rfc8285_handler, struct packet_handler_ctx *); + + const struct rtp_payload_type *rtp_get_rfc_payload_type(unsigned int type); const struct rtp_payload_type *rtp_get_rfc_codec(const str *codec);