Browse Source

MT#63317 store extmap entries in media object

Change-Id: Ia673ae3049f5c6ce8dd8516b5becc0a9322559d8
pull/2008/head
Richard Fuchs 5 months ago
parent
commit
fc9cb21d8a
6 changed files with 96 additions and 10 deletions
  1. +23
    -0
      daemon/call.c
  2. +54
    -6
      daemon/sdp.c
  3. +3
    -0
      include/call.h
  4. +10
    -0
      include/media_socket.h
  5. +2
    -2
      lib/rtplib.c
  6. +4
    -2
      t/auto-daemon-tests.pl

+ 23
- 0
daemon/call.c View File

@ -2848,6 +2848,25 @@ static void media_set_siprec_label(struct call_media *other_media, struct call_m
other_media->label = media->label;
}
__attribute__((nonnull(1, 2)))
static void media_init_extmap(struct call_media *media, struct rtp_extension *ext) {
ext->name = call_str_cpy(&ext->name);
}
__attribute__((nonnull(1, 2)))
static void media_update_extmap(struct call_media *media, struct stream_params *sp) {
// empty out old queue and take over from `sp`
t_queue_clear_full(&media->extmap, rtp_extension_free);
media->extmap = sp->extmap;
t_queue_init(&sp->extmap);
// copy strings
for (__auto_type ll = media->extmap.head; ll; ll = ll->next) {
__auto_type ext = ll->data;
media_init_extmap(media, ext);
}
}
__attribute__((nonnull(1, 2)))
static void media_init_from_flags(struct call_media *media, sdp_ng_flags *flags) {
if (flags->opmode == OP_OFFER && flags->reset) {
@ -3086,6 +3105,7 @@ static struct call_media * monologue_add_zero_media(struct call_monologue *sende
media_update_attrs(sender_media, sp);
media_update_format(sender_media, sp);
media_set_ptime(sender_media, sp, flags->rev_ptime, flags->ptime);
media_update_extmap(sender_media, sp);
*num_ports_other = proto_num_ports(sp->num_ports, sender_media, flags,
(flags->rtcp_mux_demux || flags->rtcp_mux_accept) ? true : false);
__disable_streams(sender_media, *num_ports_other);
@ -3216,6 +3236,7 @@ int monologue_offer_answer(struct call_monologue *monologues[2], sdp_streams_q *
media_set_address_family(receiver_media, sender_media, flags);
media_set_ptime(sender_media, sp, flags->rev_ptime, flags->ptime);
media_set_ptime(receiver_media, sp, flags->ptime, flags->rev_ptime);
media_update_extmap(sender_media, sp);
if (flags->opmode == OP_OFFER) {
ilog(LOG_DEBUG, "Setting media recording slots to %u", flags->media_rec_slot_offer);
@ -3631,6 +3652,7 @@ int monologue_publish(struct call_monologue *ml, sdp_streams_q *streams, sdp_ng_
media_update_attrs(media, sp);
media_update_format(media, sp);
media_set_ptime(media, sp, flags->ptime, 0);
media_update_extmap(media, sp);
codec_store_populate(&media->codecs, &sp->codecs,
.allow_asymmetric = !!flags->allow_asymmetric_codecs);
@ -4375,6 +4397,7 @@ void call_media_free(struct call_media **mdp) {
mutex_destroy(&md->dtmf_lock);
ssrc_hash_destroy(&md->ssrc_hash_in);
ssrc_hash_destroy(&md->ssrc_hash_out);
t_queue_clear_full(&md->extmap, rtp_extension_free);
g_free(md);
*mdp = NULL;
}


+ 54
- 6
daemon/sdp.c View File

@ -66,6 +66,7 @@ enum attr_id {
ATTR_TLS_ID,
ATTR_END_OF_CANDIDATES,
ATTR_MOH_ATTR_NAME,
ATTR_EXTMAP,
};
// make sure g_direct_hash can be used
static_assert(sizeof(void *) >= sizeof(enum attr_id), "sizeof enum attr_id wrong");
@ -255,9 +256,15 @@ struct attribute_t38faxudpecdepth {
int maxred;
};
struct attribute_extmap {
str id_str;
str ext;
int id;
};
enum attribute_other {
ATTR_OTHER_UNKNOWN = 0,
ATTR_OTHER_EXTMAP,
};
struct sdp_attribute {
@ -283,6 +290,7 @@ struct sdp_attribute {
int i;
struct attribute_t38faxudpecdepth t38faxudpecdepth;
struct attribute_t38faxratemanagement t38faxratemanagement;
struct attribute_extmap extmap;
enum attribute_other other;
};
};
@ -1147,6 +1155,22 @@ static bool parse_attribute_t38faxudpecdepth(struct sdp_attribute *output) {
return true;
}
static bool parse_attribute_extmap(struct sdp_attribute *output) {
output->attr = ATTR_EXTMAP;
PARSE_INIT;
EXTRACT_TOKEN(extmap.id_str);
EXTRACT_TOKEN(extmap.ext);
output->extmap.id = str_to_i(&output->extmap.id_str, 0);
// RFC 8285, valid range: 1-14, 15 reserved, 16-255, 256 appbits (not supported),
// 256-4095 invalid, 4096-4351 remap (not supported)
if (output->extmap.id <= 0 || output->extmap.id == 15 || output->extmap.id >= 256)
return false;
return true;
}
static bool parse_attribute(struct sdp_attribute *a) {
a->strs.name = a->strs.line_value;
@ -1194,7 +1218,7 @@ static bool parse_attribute(struct sdp_attribute *a) {
ret = parse_attribute_crypto(a);
break;
case CSH_LOOKUP("extmap"):
a->other = ATTR_OTHER_EXTMAP;
ret = parse_attribute_extmap(a);
break;
case CSH_LOOKUP("rtpmap"):
ret = parse_attribute_rtpmap(a);
@ -1750,6 +1774,7 @@ static void sp_free(struct stream_params *s) {
crypto_params_sdes_queue_clear(&s->sdes_params);
t_queue_clear_full(&s->generic_attributes, sdp_attr_free);
t_queue_clear_full(&s->all_attributes, sdp_attr_free);
t_queue_clear_full(&s->extmap, rtp_extension_free);
g_free(s);
}
@ -2078,6 +2103,18 @@ bool sdp_streams(const sdp_sessions_q *sessions, sdp_streams_q *streams, sdp_ng_
__sdp_t38(sp, media);
// a=extmap
attrs = attr_list_get_by_id(&media->attributes, ATTR_EXTMAP);
if (!attrs)
attrs = attr_list_get_by_id(&session->attributes, ATTR_EXTMAP);
for (__auto_type ll = attrs ? attrs->head : NULL; ll; ll = ll->next) {
attr = ll->data;
__auto_type ext = g_new0(struct rtp_extension, 1);
ext->id = attr->extmap.id;
ext->name = attr->extmap.ext;
t_queue_push_tail(&sp->extmap, ext);
}
/* determine RTCP endpoint */
if (attr_get_by_id(&media->attributes, ATTR_RTCP_MUX))
@ -2188,8 +2225,6 @@ void sdp_insert_media_attributes(GString *gs, struct call_media *media, struct c
return;
for (__auto_type l = source_media->generic_attributes.head; l; l = l->next) {
__auto_type s = l->data;
if (s->other == ATTR_OTHER_EXTMAP && flags->strip_extmap && !MEDIA_ISSET(source_media, PASSTHRU))
continue;
append_gen_attr_to_gstring(gs, &s->strs.name, &s->strs.value, flags, source_media->type_id);
}
}
@ -2203,8 +2238,6 @@ void sdp_insert_monologue_attributes(GString *gs, struct call_monologue *ml, con
for (__auto_type l = source_ml->generic_attributes.head; l; l = l->next) {
__auto_type s = l->data;
if (s->other == ATTR_OTHER_EXTMAP && flags->strip_extmap)
continue;
append_gen_attr_to_gstring(gs, &s->strs.name, &s->strs.value, flags, MT_UNKNOWN);
}
}
@ -2219,6 +2252,19 @@ void sdp_insert_all_attributes(GString *s, struct call_media *media, struct sdp_
}
}
static void sdp_print_extmap(GString *s, struct call_media *source_media, const sdp_ng_flags *flags) {
if (!source_media)
return;
if (flags->strip_extmap && !MEDIA_ISSET(source_media, PASSTHRU))
return;
for (__auto_type l = source_media->extmap.head; l; l = l->next) {
__auto_type ext = l->data;
sdp_append_attr(s, flags, source_media->type_id,
"extmap", "%u " STR_FORMAT, ext->id, STR_FMT(&ext->name));
}
}
static bool insert_ice_address(const struct sdp_state *state, stream_fd *sfd, const sdp_ng_flags *flags) {
if (!is_addr_unspecified(&flags->media_address))
sockaddr_print_gstring(state->s, &flags->media_address);
@ -2806,6 +2852,8 @@ static void print_sdp_media_section(GString *s, struct call_media *media,
if (proto_is_rtp(media->protocol))
insert_codec_parameters(s, media, flags);
sdp_print_extmap(s, source_media, flags);
/* all unknown type attributes will be added here */
media->sdp_attr_print(s, media, source_media, flags);


+ 3
- 0
include/call.h View File

@ -378,6 +378,7 @@ struct stream_params {
int media_sdp_id;
struct session_bandwidth media_session_bandiwdth;
str sdp_information;
extmap_q extmap;
};
struct endpoint_map {
@ -484,6 +485,8 @@ struct call_media {
struct ice_agent *ice_agent;
extmap_q extmap; // container
str media_id;
str label;
sdes_q sdes_in, sdes_out;


+ 10
- 0
include/media_socket.h View File

@ -280,6 +280,16 @@ struct media_packet {
int ptime; // returned from decoding
};
struct rtp_extension {
unsigned int id;
str name; // urn:ietf:params:rtp- hdrext:... or URI
};
static inline void rtp_extension_free(struct rtp_extension *r) {
g_free(r);
}
TYPED_GQUEUE(extmap, struct rtp_extension);
extern local_intf_q all_local_interfaces; // read-only during runtime


+ 2
- 2
lib/rtplib.c View File

@ -6,7 +6,7 @@
struct rtp_extension {
struct rtp_exthdr {
uint16_t undefined;
uint16_t length;
} __attribute__ ((packed));
@ -61,7 +61,6 @@ const int num_rfc_rtp_payload_types = G_N_ELEMENTS(rfc_rtp_payload_types);
struct rtp_header *rtp_payload(str *p, const str *s) {
struct rtp_header *rtp;
struct rtp_extension *ext;
const char *err;
err = "short packet (header)";
@ -86,6 +85,7 @@ struct rtp_header *rtp_payload(str *p, const str *s) {
if ((rtp->v_p_x_cc & 0x10)) {
/* extension */
struct rtp_exthdr *ext;
err = "short packet (extension header)";
if (p->len < sizeof(*ext))
goto error;


+ 4
- 2
t/auto-daemon-tests.pl View File

@ -4386,13 +4386,13 @@ a=rtpmap:126 H264/90000
a=fmtp:126 profile-level-id=428016;packetization-mode=1;max-mbps=490000;max-fs=8160;max-cpb=200;max-dpb=16320;max-br=5000;max-smbps=490000;max-fps=6000
a=rtpmap:123 X-ULPFECUC/90000
a=fmtp:123 multi_ssrc=1;feedback=0;max_esel=1450;m=8;max_n=42;FEC_ORDER=FEC_SRTP;non_seq=1
a=extmap:4 http://protocols.cisco.com/timestamp#100us
a=rtcp-fb:* ccm pan
a=rtcp-fb:* nack pli
a=rtcp-fb:* ccm fir
a=rtcp-fb:* ccm tmmbr
a=label:11
a=answer:full
a=extmap:4 http://protocols.cisco.com/timestamp#100us
a=cisco-mari-psre:97 ltrf=3
a=cisco-mari-psre:126 ltrf=3
a=content:main
@ -21518,6 +21518,7 @@ t=0 0
m=audio 2000 RTP/AVP 0
c=IN IP4 198.51.100.1
a=extmap:0 foobar
a=extmap:1 quux
a=sendrecv
----------------------------------
v=0
@ -21527,7 +21528,7 @@ t=0 0
m=audio PORT RTP/AVP 0
c=IN IP4 203.0.113.1
a=rtpmap:0 PCMU/8000
a=extmap:0 foobar
a=extmap:1 quux
a=sendrecv
a=rtcp:PORT
SDP
@ -21542,6 +21543,7 @@ t=0 0
m=audio 2000 RTP/AVP 0
c=IN IP4 198.51.100.1
a=extmap:0 foobar
a=extmap:1 quux
a=sendrecv
----------------------------------
v=0


Loading…
Cancel
Save