TT#54800 fix ptime overrides

Adds a new option ptime-reverse to complement setting of ptime towards
the offerer. This and ptime setting are now ignored in answers.

Change-Id: Icbc04f191cbc194b75b72a97832fcaba58feb10e
changes/68/27968/5
Richard Fuchs 6 years ago
parent 6921472e3b
commit fb76ef74f8

@ -992,6 +992,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

@ -1870,11 +1870,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);

@ -807,7 +807,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))

@ -1252,6 +1252,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);
@ -1262,6 +1265,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);
@ -1277,8 +1283,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) {
@ -1428,6 +1434,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);

@ -147,6 +147,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)

@ -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,

@ -2040,6 +2040,79 @@ rcv($sock_a, $port_b, rtpm(0, 4002, 5800, $ssrc, "\x88" x 400));
($sock_a, $sock_b) = new_call([qw(198.51.100.1 3012)], [qw(198.51.100.3 3014)]);
($port_a) = offer('ptime=50 in, change to 30, response 30, no change', {
ICE => 'remove', replace => ['origin'], ptime => 30 }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio 3012 RTP/AVP 0
c=IN IP4 198.51.100.1
a=sendrecv
a=ptime:50
----------------------------------
v=0
o=- 1545997027 1 IN IP4 203.0.113.1
s=tester
t=0 0
m=audio PORT RTP/AVP 0
c=IN IP4 203.0.113.1
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:PORT
a=ptime:30
SDP
($port_b) = answer('ptime=50 in, change to 30, response 30, no change',
{ ICE => 'remove', replace => ['origin'] }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.3
s=tester
t=0 0
m=audio 3014 RTP/AVP 0
c=IN IP4 198.51.100.3
a=sendrecv
a=ptime:30
--------------------------------------
v=0
o=- 1545997027 1 IN IP4 203.0.113.1
s=tester
t=0 0
m=audio PORT RTP/AVP 0
c=IN IP4 203.0.113.1
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:PORT
a=ptime:50
SDP
# A->B: 2x 50 ms -> 3x 30 ms (plus 10 ms left)
snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\00" x 400));
($ssrc) = rcv($sock_b, $port_a, rtpm(0, 1000, 3000, -1, "\00" x 240));
snd($sock_a, $port_b, rtp(0, 1001, 3400, 0x1234, "\00" x 400));
rcv($sock_b, $port_a, rtpm(0, 1001, 3240, $ssrc, "\00" x 240));
rcv($sock_b, $port_a, rtpm(0, 1002, 3480, $ssrc, "\00" x 240));
# A->B: add another 20 ms for another full 30 ms
snd($sock_a, $port_b, rtp(0, 1002, 3800, 0x1234, "\00" x 160));
rcv($sock_b, $port_a, rtpm(0, 1003, 3720, $ssrc, "\00" x 240));
# B->A: 4x 30 ms -> 2x 50 ms (plus 20 ms left)
snd($sock_b, $port_a, rtp(0, 4000, 5000, 0x4567, "\x88" x 240));
Time::HiRes::usleep(20000); # 20 ms, needed to ensure that packet 1000 is received first
snd($sock_b, $port_a, rtp(0, 4001, 5240, 0x4567, "\x88" x 240));
($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 5000, -1, "\x88" x 400));
snd($sock_b, $port_a, rtp(0, 4002, 5480, 0x4567, "\x88" x 240));
snd($sock_b, $port_a, rtp(0, 4003, 5720, 0x4567, "\x88" x 240));
rcv($sock_a, $port_b, rtpm(0, 4001, 5400, $ssrc, "\x88" x 400));
# B->A: add another 30 ms for another full 50 ms
snd($sock_b, $port_a, rtp(0, 4004, 5960, 0x4567, "\x88" x 240));
rcv($sock_a, $port_b, rtpm(0, 4002, 5800, $ssrc, "\x88" x 400));
END {
if ($rtpe_pid) {
kill('INT', $rtpe_pid) or die;

Loading…
Cancel
Save