diff --git a/README.md b/README.md index 5db39e7fb..cf3477d10 100644 --- a/README.md +++ b/README.md @@ -1534,6 +1534,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 e425d69a4..c142d05b8 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1788,11 +1788,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->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 9cf023b65..8b2b9f369 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -645,12 +645,13 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) { STR_FMT(s)); } } -static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *input) { +static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *input, enum call_opmode opmode) { bencode_item_t *list, *it, *dict; int diridx; str s; ZERO(*out); + out->opmode = opmode; out->codec_strip = g_hash_table_new_full(str_hash, str_equal, str_slice_free, NULL); out->codec_mask = g_hash_table_new_full(str_hash, str_equal, str_slice_free, NULL); @@ -710,7 +711,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)) @@ -816,8 +823,7 @@ static const char *call_offer_answer_ng(bencode_item_t *input, bencode_dictionary_get_str(input, "via-branch", &viabranch); bencode_dictionary_get_str(input, "label", &label); - call_ng_process_flags(&flags, input); - flags.opmode = opmode; + call_ng_process_flags(&flags, input, opmode); if (opmode == OP_OFFER) { enum load_limit_reasons limit = call_offer_session_limit(); @@ -1446,7 +1452,7 @@ const char *call_unblock_dtmf_ng(bencode_item_t *input, bencode_item_t *output) if (errstr) goto out; - call_ng_process_flags(&flags, input); + call_ng_process_flags(&flags, input, OP_OTHER); if (monologue) { ilog(LOG_INFO, "Unblocking directional DTMF (tag '" STR_FORMAT ")", @@ -1515,7 +1521,7 @@ const char *call_unblock_media_ng(bencode_item_t *input, bencode_item_t *output) if (errstr) goto out; - call_ng_process_flags(&flags, input); + call_ng_process_flags(&flags, input, OP_OTHER); if (monologue) { ilog(LOG_INFO, "Unblocking directional media (tag '" STR_FORMAT ")", diff --git a/daemon/codec.c b/daemon/codec.c index eafa8f84b..e09a82257 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -1097,6 +1097,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); @@ -1107,6 +1110,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); @@ -1122,8 +1128,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) { @@ -1243,6 +1249,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 5db4a16b4..25e5fe488 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 e87318a4b..af0fef6e0 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -36,7 +36,8 @@ struct sdp_ng_flags { GQueue codec_offer; GQueue codec_transcode; GHashTable *codec_mask; - int ptime; + int ptime, + rev_ptime; int asymmetric:1, no_redis_update:1, unidirectional:1,