diff --git a/daemon/call.c b/daemon/call.c index 790f6506e..da9e3b350 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1861,7 +1861,8 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, /* copy parameters advertised by the sender of this message */ bf_copy_same(&other_media->media_flags, &sp->sp_flags, SHARED_FLAG_RTCP_MUX | SHARED_FLAG_ASYMMETRIC | SHARED_FLAG_UNIDIRECTIONAL | - SHARED_FLAG_ICE | SHARED_FLAG_TRICKLE_ICE | SHARED_FLAG_ICE_LITE); + SHARED_FLAG_ICE | SHARED_FLAG_TRICKLE_ICE | SHARED_FLAG_ICE_LITE | + SHARED_FLAG_RTCP_FB); // steal the entire queue of offered crypto params crypto_params_sdes_queue_clear(&other_media->sdes_in); diff --git a/daemon/media_player.c b/daemon/media_player.c index 236775409..e8dd70037 100644 --- a/daemon/media_player.c +++ b/daemon/media_player.c @@ -395,7 +395,7 @@ found: } mp->media = media; mp->sink = media->streams.head->data; - mp->crypt_handler = determine_handler(&transport_protocols[PROTO_RTP_AVP], media->protocol, 1); + mp->crypt_handler = determine_handler(&transport_protocols[PROTO_RTP_AVP], media, 1); return 0; } diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 2484e7f26..a673f556d 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -93,6 +93,7 @@ const struct transport_protocol transport_protocols[] = { [PROTO_RTP_AVP] = { .index = PROTO_RTP_AVP, .name = "RTP/AVP", + .avpf_proto = PROTO_RTP_AVPF, .rtp = 1, .srtp = 0, .avpf = 0, @@ -101,6 +102,7 @@ const struct transport_protocol transport_protocols[] = { [PROTO_RTP_SAVP] = { .index = PROTO_RTP_SAVP, .name = "RTP/SAVP", + .avpf_proto = PROTO_RTP_SAVPF, .rtp = 1, .srtp = 1, .avpf = 0, @@ -125,6 +127,7 @@ const struct transport_protocol transport_protocols[] = { [PROTO_UDP_TLS_RTP_SAVP] = { .index = PROTO_UDP_TLS_RTP_SAVP, .name = "UDP/TLS/RTP/SAVP", + .avpf_proto = PROTO_UDP_TLS_RTP_SAVPF, .rtp = 1, .srtp = 1, .avpf = 0, @@ -1177,8 +1180,9 @@ void unkernelize(struct packet_stream *ps) { const struct streamhandler *determine_handler(const struct transport_protocol *in_proto, - const struct transport_protocol *out_proto, int must_recrypt) + struct call_media *out_media, int must_recrypt) { + const struct transport_protocol *out_proto = out_media->protocol; const struct streamhandler * const *sh_pp, *sh; const struct streamhandler * const * const *matrix; @@ -1189,7 +1193,15 @@ const struct streamhandler *determine_handler(const struct transport_protocol *i sh_pp = matrix[in_proto->index]; if (!sh_pp) goto err; - sh = sh_pp[out_proto->index]; + + // special handling for RTP/AVP with advertised a=rtcp-fb + int out_proto_idx = out_proto->index; + if (out_media && MEDIA_ISSET(out_media, RTCP_FB)) { + if (!out_proto->avpf && out_proto->avpf_proto) + out_proto_idx = out_proto->avpf_proto; + } + sh = sh_pp[out_proto_idx]; + if (!sh) goto err; return sh; @@ -1227,7 +1239,7 @@ static void __determine_handler(struct packet_stream *in, const struct packet_st || crypto_params_cmp(&out->crypto.params, &in->selected_sfd->crypto.params))) must_recrypt = 1; - in->handler = determine_handler(in_proto, out_proto, must_recrypt); + in->handler = determine_handler(in_proto, out->media, must_recrypt); return; err: diff --git a/daemon/sdp.c b/daemon/sdp.c index 9e6176b0b..3ad9c1764 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -203,6 +203,7 @@ struct sdp_attribute { /* example: a=rtpmap:8 PCMA/8000 */ ATTR_IGNORE, ATTR_RTPENGINE, ATTR_PTIME, + ATTR_RTCP_FB, ATTR_END_OF_CANDIDATES, } attr; @@ -869,6 +870,9 @@ static int parse_attribute(struct sdp_attribute *a) { case CSH_LOOKUP("end-of-candidates"): a->attr = ATTR_END_OF_CANDIDATES; break; + case CSH_LOOKUP("rtcp-fb"): + a->attr = ATTR_RTCP_FB; + break; } return ret; @@ -1330,6 +1334,10 @@ int sdp_streams(const GQueue *sessions, GQueue *streams, struct sdp_ng_flags *fl if (attr) sp->media_id = attr->value; + // be ignorant about the contents + if (attr_get_by_id(&media->attributes, ATTR_RTCP_FB)) + SP_SET(sp, RTCP_FB); + __sdp_ice(sp, media); /* determine RTCP endpoint */ diff --git a/include/call.h b/include/call.h index c06066dde..106b5bc14 100644 --- a/include/call.h +++ b/include/call.h @@ -95,6 +95,7 @@ enum call_type { #define SHARED_FLAG_TRICKLE_ICE 0x00000400 #define SHARED_FLAG_ICE_LITE 0x00000800 #define SHARED_FLAG_UNIDIRECTIONAL 0x00001000 +#define SHARED_FLAG_RTCP_FB 0x00002000 /* struct stream_params */ #define SP_FLAG_NO_RTCP 0x00010000 @@ -111,6 +112,7 @@ enum call_type { #define SP_FLAG_MEDIA_HANDOVER SHARED_FLAG_MEDIA_HANDOVER #define SP_FLAG_TRICKLE_ICE SHARED_FLAG_TRICKLE_ICE #define SP_FLAG_ICE_LITE SHARED_FLAG_ICE_LITE +#define SP_FLAG_RTCP_FB SHARED_FLAG_RTCP_FB /* struct packet_stream */ #define PS_FLAG_RTP 0x00010000 @@ -148,6 +150,7 @@ enum call_type { #define MEDIA_FLAG_LOOP_CHECK 0x00400000 #define MEDIA_FLAG_TRANSCODE 0x00800000 #define MEDIA_FLAG_PTIME_OVERRIDE 0x01000000 +#define MEDIA_FLAG_RTCP_FB SHARED_FLAG_RTCP_FB /* access macros */ #define SP_ISSET(p, f) bf_isset(&(p)->sp_flags, SP_FLAG_ ## f) diff --git a/include/media_socket.h b/include/media_socket.h index b5da2c9d5..438e73f25 100644 --- a/include/media_socket.h +++ b/include/media_socket.h @@ -39,6 +39,7 @@ enum transport_protocol_index { struct transport_protocol { enum transport_protocol_index index; const char *name; + enum transport_protocol_index avpf_proto; int rtp:1; /* also set to 1 for SRTP */ int srtp:1; int avpf:1; @@ -169,7 +170,7 @@ void __stream_unconfirm(struct packet_stream *); int media_socket_dequeue(struct media_packet *mp, struct packet_stream *sink); const struct streamhandler *determine_handler(const struct transport_protocol *in_proto, - const struct transport_protocol *out_proto, int must_recrypt); + struct call_media *out_media, int must_recrypt); int media_packet_encrypt(rewrite_func encrypt_func, struct packet_stream *out, struct media_packet *mp); const struct transport_protocol *transport_protocol(const str *s);