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 7 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 been requested for transcoding. Note that not all codecs support all packetization
intervals. 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` * `supports`
Contains a list of strings. Each string indicates support for an additional feature 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 // codec and RTP payload types handling
if (sp->ptime > 0) { if (sp->ptime > 0) {
media->ptime = sp->ptime; if (!MEDIA_ISSET(media, PTIME_OVERRIDE))
other_media->ptime = sp->ptime; 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->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_rtp_payload_types(media, other_media, &sp->rtp_payload_types, flags);
codec_handlers_update(media, other_media, 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); out->tos = bencode_dictionary_get_int_str(input, "TOS", 256);
bencode_get_alt(input, "record-call", "record call", &out->record_call_str); bencode_get_alt(input, "record-call", "record call", &out->record_call_str);
bencode_dictionary_get_str(input, "metadata", &out->metadata); 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 (bencode_dictionary_get_str(input, "xmlrpc-callback", &s)) {
if (sockaddr_parse_any_str(&out->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) if (!pt)
return; 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); g_hash_table_insert(media->codecs_recv, &pt->payload_type, pt);
__rtp_payload_type_add_name(media->codec_names_recv, pt); __rtp_payload_type_add_name(media->codec_names_recv, pt);
g_queue_push_tail(&media->codecs_prefs_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) if (!pt)
return; 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); g_hash_table_insert(other_media->codecs_send, &pt->payload_type, pt);
__rtp_payload_type_add_name(other_media->codec_names_send, pt); __rtp_payload_type_add_name(other_media->codec_names_send, pt);
g_queue_push_tail(&other_media->codecs_prefs_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, static void __rtp_payload_type_add(struct call_media *media, struct call_media *other_media,
struct rtp_payload_type *pt) 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_send_dup(other_media, pt);
__rtp_payload_type_add_recv(media, pt);
} }
static void __payload_queue_free(void *qq) { 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); STR_FMT(&pt->encoding_with_params), pt->payload_type);
__rtp_payload_type_add_recv(media, pt); __rtp_payload_type_add_recv(media, pt);
} }
#endif #endif
g_hash_table_destroy(removed); g_hash_table_destroy(removed);

@ -147,6 +147,7 @@ enum call_type {
#define MEDIA_FLAG_ICE_CONTROLLING 0x00200000 #define MEDIA_FLAG_ICE_CONTROLLING 0x00200000
#define MEDIA_FLAG_LOOP_CHECK 0x00400000 #define MEDIA_FLAG_LOOP_CHECK 0x00400000
#define MEDIA_FLAG_TRANSCODE 0x00800000 #define MEDIA_FLAG_TRANSCODE 0x00800000
#define MEDIA_FLAG_PTIME_OVERRIDE 0x01000000
/* access macros */ /* access macros */
#define SP_ISSET(p, f) bf_isset(&(p)->sp_flags, SP_FLAG_ ## f) #define SP_ISSET(p, f) bf_isset(&(p)->sp_flags, SP_FLAG_ ## f)

@ -37,7 +37,8 @@ struct sdp_ng_flags {
GQueue codec_transcode; GQueue codec_transcode;
GHashTable *codec_mask; GHashTable *codec_mask;
GHashTable *codec_set; GHashTable *codec_set;
int ptime; int ptime,
rev_ptime;
GHashTable *sdes_no; GHashTable *sdes_no;
int asymmetric:1, int asymmetric:1,
no_redis_update: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 { END {
if ($rtpe_pid) { if ($rtpe_pid) {
kill('INT', $rtpe_pid) or die; kill('INT', $rtpe_pid) or die;

Loading…
Cancel
Save