diff --git a/README.md b/README.md index f6b8f7f83..0a0c3fdbf 100644 --- a/README.md +++ b/README.md @@ -1596,6 +1596,18 @@ Optionally included keys are: been requested for transcoding. Note that not all codecs support all packetization intervals. + The selected ptime (which represents the duration of a single media packet in milliseconds) + will be used towards the endpoint receiving this offer, even if the matching answer + prefers a different ptime. + + This option is ignored in `answer` messages. See below for the reverse. + +* `ptime-reverse` + + This is the reciprocal to `ptime`. It sets the ptime to be used towards the endpoint + who has sent the offer. It will be inserted in the `answer` SDP. This option is also + ignored in `answer` messages. + * `supports` Contains a list of strings. Each string indicates support for an additional feature diff --git a/daemon/call.c b/daemon/call.c index 6ce545685..3ad8ff7a8 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1927,11 +1927,21 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, // codec and RTP payload types handling if (sp->ptime > 0) { - media->ptime = sp->ptime; - other_media->ptime = sp->ptime; + if (!MEDIA_ISSET(media, PTIME_OVERRIDE)) + media->ptime = sp->ptime; + if (!MEDIA_ISSET(other_media, PTIME_OVERRIDE)) + other_media->ptime = sp->ptime; } - if (flags && flags->ptime > 0) + if (flags && flags->ptime > 0) { media->ptime = flags->ptime; + MEDIA_SET(media, PTIME_OVERRIDE); + MEDIA_SET(other_media, PTIME_OVERRIDE); + } + if (flags && flags->rev_ptime > 0) { + other_media->ptime = flags->rev_ptime; + MEDIA_SET(media, PTIME_OVERRIDE); + MEDIA_SET(other_media, PTIME_OVERRIDE); + } codec_rtp_payload_types(media, other_media, &sp->rtp_payload_types, flags); codec_handlers_update(media, other_media, flags); diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index d7adeec08..b1df41273 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -804,7 +804,13 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu out->tos = bencode_dictionary_get_int_str(input, "TOS", 256); bencode_get_alt(input, "record-call", "record call", &out->record_call_str); bencode_dictionary_get_str(input, "metadata", &out->metadata); - out->ptime = bencode_dictionary_get_int_str(input, "ptime", 0); + + if (opmode == OP_OFFER) { + out->ptime = bencode_dictionary_get_int_str(input, "ptime", 0); + out->rev_ptime = bencode_dictionary_get_int_str(input, "ptime-reverse", 0); + if (out->rev_ptime == 0) + out->rev_ptime = bencode_dictionary_get_int_str(input, "ptime reverse", 0); + } if (bencode_dictionary_get_str(input, "xmlrpc-callback", &s)) { if (sockaddr_parse_any_str(&out->xmlrpc_callback, &s)) diff --git a/daemon/codec.c b/daemon/codec.c index f3f22ab3d..c5feb84e4 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -1134,6 +1134,9 @@ void __rtp_payload_type_add_recv(struct call_media *media, { if (!pt) return; + // update ptime in case it was overridden + if (media->ptime > 0) + pt->ptime = media->ptime; g_hash_table_insert(media->codecs_recv, &pt->payload_type, pt); __rtp_payload_type_add_name(media->codec_names_recv, pt); g_queue_push_tail(&media->codecs_prefs_recv, pt); @@ -1144,6 +1147,9 @@ void __rtp_payload_type_add_send(struct call_media *other_media, { if (!pt) return; + // update ptime in case it was overridden + if (other_media->ptime > 0) + pt->ptime = other_media->ptime; g_hash_table_insert(other_media->codecs_send, &pt->payload_type, pt); __rtp_payload_type_add_name(other_media->codec_names_send, pt); g_queue_push_tail(&other_media->codecs_prefs_send, pt); @@ -1159,8 +1165,8 @@ void __rtp_payload_type_add_send_dup(struct call_media *other_media, static void __rtp_payload_type_add(struct call_media *media, struct call_media *other_media, struct rtp_payload_type *pt) { - __rtp_payload_type_add_recv(media, pt); __rtp_payload_type_add_send_dup(other_media, pt); + __rtp_payload_type_add_recv(media, pt); } static void __payload_queue_free(void *qq) { @@ -1310,6 +1316,7 @@ void codec_rtp_payload_types(struct call_media *media, struct call_media *other_ STR_FMT(&pt->encoding_with_params), pt->payload_type); __rtp_payload_type_add_recv(media, pt); } + #endif g_hash_table_destroy(removed); diff --git a/include/call.h b/include/call.h index a665d1e69..6eaaaacdf 100644 --- a/include/call.h +++ b/include/call.h @@ -165,6 +165,7 @@ enum call_type { #define MEDIA_FLAG_ICE_CONTROLLING 0x00200000 #define MEDIA_FLAG_LOOP_CHECK 0x00400000 #define MEDIA_FLAG_TRANSCODE 0x00800000 +#define MEDIA_FLAG_PTIME_OVERRIDE 0x01000000 /* access macros */ #define SP_ISSET(p, f) bf_isset(&(p)->sp_flags, SP_FLAG_ ## f) diff --git a/include/call_interfaces.h b/include/call_interfaces.h index 10a0e0b4b..ed2fe7e33 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -37,7 +37,8 @@ struct sdp_ng_flags { GQueue codec_transcode; GHashTable *codec_mask; GHashTable *codec_set; - int ptime; + int ptime, + rev_ptime; GHashTable *sdes_no; int asymmetric:1, no_redis_update:1,