TT#76250 consider default number of channel when matching codecs

Eliminates duplicated codecs when `opus/48000/1` is used for example

Change-Id: If434e34fe75883544cf6c2c83723af73878ccb20
pull/1179/head
Richard Fuchs 5 years ago
parent 9c6d57edc5
commit c5ef68897a

@ -41,6 +41,7 @@ static GList *__delete_x_codec(GList *link, GHashTable *codecs, GHashTable *code
g_hash_table_remove(codecs, &pt->payload_type); g_hash_table_remove(codecs, &pt->payload_type);
g_hash_table_remove(codec_names, &pt->encoding); g_hash_table_remove(codec_names, &pt->encoding);
g_hash_table_remove(codec_names, &pt->encoding_with_params); g_hash_table_remove(codec_names, &pt->encoding_with_params);
g_hash_table_remove(codec_names, &pt->encoding_with_full_params);
GList *next = link->next; GList *next = link->next;
g_queue_delete_link(codecs_prefs, link); g_queue_delete_link(codecs_prefs, link);
@ -984,6 +985,7 @@ static void __check_dtmf_injector(const struct sdp_ng_flags *flags, struct call_
}; };
str_init(&src_pt.encoding, "DTMF injector"); str_init(&src_pt.encoding, "DTMF injector");
str_init(&src_pt.encoding_with_params, "DTMF injector"); str_init(&src_pt.encoding_with_params, "DTMF injector");
str_init(&src_pt.encoding_with_full_params, "DTMF injector");
const str tp_event = STR_CONST_INIT("telephone-event"); const str tp_event = STR_CONST_INIT("telephone-event");
src_pt.codec_def = codec_find(&tp_event, MT_AUDIO); src_pt.codec_def = codec_find(&tp_event, MT_AUDIO);
if (!src_pt.codec_def) { if (!src_pt.codec_def) {
@ -2215,12 +2217,15 @@ void codec_init_payload_type(struct rtp_payload_type *ret, struct call_media *me
// init params strings // init params strings
char full_encoding[64]; char full_encoding[64];
char full_full_encoding[64];
char params[32] = ""; char params[32] = "";
snprintf(full_full_encoding, sizeof(full_full_encoding), STR_FORMAT "/%u/%i", STR_FMT(&ret->encoding),
ret->clock_rate,
ret->channels);
if (ret->channels > 1) { if (ret->channels > 1) {
snprintf(full_encoding, sizeof(full_encoding), STR_FORMAT "/%u/%i", STR_FMT(&ret->encoding), strcpy(full_encoding, full_full_encoding);
ret->clock_rate,
ret->channels);
snprintf(params, sizeof(params), "%i", ret->channels); snprintf(params, sizeof(params), "%i", ret->channels);
} }
else else
@ -2228,6 +2233,7 @@ void codec_init_payload_type(struct rtp_payload_type *ret, struct call_media *me
ret->clock_rate); ret->clock_rate);
str_init(&ret->encoding_with_params, full_encoding); str_init(&ret->encoding_with_params, full_encoding);
str_init(&ret->encoding_with_full_params, full_full_encoding);
str_init(&ret->encoding_parameters, params); str_init(&ret->encoding_parameters, params);
if (media) if (media)
@ -3107,6 +3113,17 @@ static struct rtp_payload_type *codec_add_payload_type(const str *codec, struct
static void __rtp_payload_type_dup(struct call *call, struct rtp_payload_type *pt) { static void __rtp_payload_type_dup(struct call *call, struct rtp_payload_type *pt) {
/* we must duplicate the contents */ /* we must duplicate the contents */
call_str_cpy(call, &pt->encoding_with_params, &pt->encoding_with_params); call_str_cpy(call, &pt->encoding_with_params, &pt->encoding_with_params);
// special handling of this one as it's not done by the SDP parser
if (pt->encoding_with_full_params.len)
call_str_cpy(call, &pt->encoding_with_full_params, &pt->encoding_with_full_params);
else {
char buf[64];
snprintf(buf, sizeof(buf), STR_FORMAT "/%i/%i", STR_FMT(&pt->encoding),
pt->clock_rate, pt->channels);
str s;
str_init(&s, buf);
call_str_cpy(call, &pt->encoding_with_full_params, &s);
}
call_str_cpy(call, &pt->encoding, &pt->encoding); call_str_cpy(call, &pt->encoding, &pt->encoding);
call_str_cpy(call, &pt->encoding_parameters, &pt->encoding_parameters); call_str_cpy(call, &pt->encoding_parameters, &pt->encoding_parameters);
call_str_cpy(call, &pt->format_parameters, &pt->format_parameters); call_str_cpy(call, &pt->format_parameters, &pt->format_parameters);
@ -3124,6 +3141,8 @@ static void __rtp_payload_type_add_name(GHashTable *ht, struct rtp_payload_type
g_queue_push_tail(q, GUINT_TO_POINTER(pt->payload_type)); g_queue_push_tail(q, GUINT_TO_POINTER(pt->payload_type));
q = g_hash_table_lookup_queue_new(ht, str_dup(&pt->encoding_with_params), free); q = g_hash_table_lookup_queue_new(ht, str_dup(&pt->encoding_with_params), free);
g_queue_push_tail(q, GUINT_TO_POINTER(pt->payload_type)); g_queue_push_tail(q, GUINT_TO_POINTER(pt->payload_type));
q = g_hash_table_lookup_queue_new(ht, str_dup(&pt->encoding_with_full_params), free);
g_queue_push_tail(q, GUINT_TO_POINTER(pt->payload_type));
} }
#ifdef WITH_TRANSCODING #ifdef WITH_TRANSCODING
static void __insert_codec_tracker(struct call_media *media, GList *link) { static void __insert_codec_tracker(struct call_media *media, GList *link) {
@ -3290,6 +3309,8 @@ static int __codec_options_set1(struct call *call, struct rtp_payload_type *pt,
static void __codec_options_set(struct call *call, struct rtp_payload_type *pt, GHashTable *codec_set) { static void __codec_options_set(struct call *call, struct rtp_payload_type *pt, GHashTable *codec_set) {
if (!codec_set) if (!codec_set)
return; return;
if (__codec_options_set1(call, pt, &pt->encoding_with_full_params, codec_set))
return;
if (__codec_options_set1(call, pt, &pt->encoding_with_params, codec_set)) if (__codec_options_set1(call, pt, &pt->encoding_with_params, codec_set))
return; return;
if (__codec_options_set1(call, pt, &pt->encoding, codec_set)) if (__codec_options_set1(call, pt, &pt->encoding, codec_set))
@ -3506,12 +3527,16 @@ int __codec_ht_except(int all_flag, GHashTable *yes_ht, GHashTable *no_ht, struc
do_this = 1; do_this = 1;
else if (g_hash_table_lookup(yes_ht, &pt->encoding_with_params)) else if (g_hash_table_lookup(yes_ht, &pt->encoding_with_params))
do_this = 1; do_this = 1;
else if (g_hash_table_lookup(yes_ht, &pt->encoding_with_full_params))
do_this = 1;
} }
if (no_ht && all_flag) { if (no_ht && all_flag) {
if (g_hash_table_lookup(no_ht, &pt->encoding)) if (g_hash_table_lookup(no_ht, &pt->encoding))
do_this = 0; do_this = 0;
else if (g_hash_table_lookup(no_ht, &pt->encoding_with_params)) else if (g_hash_table_lookup(no_ht, &pt->encoding_with_params))
do_this = 0; do_this = 0;
else if (g_hash_table_lookup(no_ht, &pt->encoding_with_full_params))
do_this = 0;
} }
return do_this; return do_this;
} }
@ -3595,6 +3620,8 @@ void codec_rtp_payload_types(struct call_media *media, struct call_media *other_
#endif #endif
GQueue *q = g_hash_table_lookup_queue_new(stripped, str_dup(&pt->encoding), free); GQueue *q = g_hash_table_lookup_queue_new(stripped, str_dup(&pt->encoding), free);
g_queue_push_tail(q, __rtp_payload_type_copy(pt)); g_queue_push_tail(q, __rtp_payload_type_copy(pt));
q = g_hash_table_lookup_queue_new(stripped, str_dup(&pt->encoding_with_full_params), free);
g_queue_push_tail(q, __rtp_payload_type_copy(pt));
q = g_hash_table_lookup_queue_new(stripped, str_dup(&pt->encoding_with_params), free); q = g_hash_table_lookup_queue_new(stripped, str_dup(&pt->encoding_with_params), free);
g_queue_push_tail(q, pt); g_queue_push_tail(q, pt);
continue; continue;
@ -3616,6 +3643,8 @@ void codec_rtp_payload_types(struct call_media *media, struct call_media *other_
GQueue *q = g_hash_table_lookup_queue_new(masked, str_dup(&pt->encoding), free); GQueue *q = g_hash_table_lookup_queue_new(masked, str_dup(&pt->encoding), free);
g_queue_push_tail(q, __rtp_payload_type_copy(pt)); g_queue_push_tail(q, __rtp_payload_type_copy(pt));
q = g_hash_table_lookup_queue_new(masked, str_dup(&pt->encoding_with_full_params), free);
g_queue_push_tail(q, __rtp_payload_type_copy(pt));
q = g_hash_table_lookup_queue_new(masked, str_dup(&pt->encoding_with_params), free); q = g_hash_table_lookup_queue_new(masked, str_dup(&pt->encoding_with_params), free);
g_queue_push_tail(q, __rtp_payload_type_copy(pt)); g_queue_push_tail(q, __rtp_payload_type_copy(pt));
__rtp_payload_type_add_send(other_media, pt); __rtp_payload_type_add_send(other_media, pt);
@ -3629,6 +3658,8 @@ void codec_rtp_payload_types(struct call_media *media, struct call_media *other_
pt->for_transcoding = 1; pt->for_transcoding = 1;
GQueue *q = g_hash_table_lookup_queue_new(masked, str_dup(&pt->encoding), free); GQueue *q = g_hash_table_lookup_queue_new(masked, str_dup(&pt->encoding), free);
g_queue_push_tail(q, __rtp_payload_type_copy(pt)); g_queue_push_tail(q, __rtp_payload_type_copy(pt));
q = g_hash_table_lookup_queue_new(masked, str_dup(&pt->encoding_with_full_params), free);
g_queue_push_tail(q, __rtp_payload_type_copy(pt));
q = g_hash_table_lookup_queue_new(masked, str_dup(&pt->encoding_with_params), free); q = g_hash_table_lookup_queue_new(masked, str_dup(&pt->encoding_with_params), free);
g_queue_push_tail(q, __rtp_payload_type_copy(pt)); g_queue_push_tail(q, __rtp_payload_type_copy(pt));
__rtp_payload_type_add_send(other_media, pt); __rtp_payload_type_add_send(other_media, pt);

@ -19,6 +19,7 @@ struct rtp_header {
struct rtp_payload_type { struct rtp_payload_type {
int payload_type; int payload_type;
str encoding_with_params; // "opus/48000/2" str encoding_with_params; // "opus/48000/2"
str encoding_with_full_params; // "opus/48000/1"
str encoding; // "opus" str encoding; // "opus"
unsigned int clock_rate; // 48000 unsigned int clock_rate; // 48000
str encoding_parameters; // "2" str encoding_parameters; // "2"

@ -3201,9 +3201,9 @@ o=- 3815883745 3815883745 IN IP4 ims.imscore.net
s=- s=-
c=IN IP4 203.0.113.1 c=IN IP4 203.0.113.1
t=0 0 t=0 0
m=audio PORT RTP/AVP 9 97 8 101 96 m=audio PORT RTP/AVP 9 111 8 101 96
a=rtpmap:9 G722/8000 a=rtpmap:9 G722/8000
a=rtpmap:97 opus/48000 a=rtpmap:111 opus/48000
a=rtpmap:8 PCMA/8000 a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/48000 a=rtpmap:101 telephone-event/48000
a=fmtp:101 0-15 a=fmtp:101 0-15

@ -998,6 +998,94 @@ SDP
# dup codec
new_call();
offer('dup codec 1',
{ replace => ['origin'], codec => {
transcode => ['opus/48000/1', 'opus/48000/2']
} }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.101.1
s=tester
t=0 0
m=audio 3000 RTP/AVP 0 97 98
c=IN IP4 198.51.101.1
a=rtpmap:97 opus/48000
a=rtpmap:98 opus/48000/2
----------------------------------
v=0
o=- 1545997027 1 IN IP4 203.0.113.1
s=tester
t=0 0
m=audio PORT RTP/AVP 0 97 98
c=IN IP4 203.0.113.1
a=rtpmap:0 PCMU/8000
a=rtpmap:97 opus/48000
a=rtpmap:98 opus/48000/2
a=sendrecv
a=rtcp:PORT
SDP
new_call();
offer('dup codec 2',
{ replace => ['origin'], codec => {
transcode => ['opus/48000', 'opus/48000/2']
} }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.101.1
s=tester
t=0 0
m=audio 3000 RTP/AVP 0 97 98
c=IN IP4 198.51.101.1
a=rtpmap:97 opus/48000
a=rtpmap:98 opus/48000/2
----------------------------------
v=0
o=- 1545997027 1 IN IP4 203.0.113.1
s=tester
t=0 0
m=audio PORT RTP/AVP 0 97 98
c=IN IP4 203.0.113.1
a=rtpmap:0 PCMU/8000
a=rtpmap:97 opus/48000
a=rtpmap:98 opus/48000/2
a=sendrecv
a=rtcp:PORT
SDP
new_call();
offer('dup codec 3',
{ replace => ['origin'], codec => {
transcode => ['opus', 'opus/48000/2']
} }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.101.1
s=tester
t=0 0
m=audio 3000 RTP/AVP 0 97 98
c=IN IP4 198.51.101.1
a=rtpmap:97 opus/48000
a=rtpmap:98 opus/48000/2
----------------------------------
v=0
o=- 1545997027 1 IN IP4 203.0.113.1
s=tester
t=0 0
m=audio PORT RTP/AVP 0 97 98
c=IN IP4 203.0.113.1
a=rtpmap:0 PCMU/8000
a=rtpmap:97 opus/48000
a=rtpmap:98 opus/48000/2
a=sendrecv
a=rtcp:PORT
SDP
@ -3211,9 +3299,9 @@ o=- 3815883745 3815883745 IN IP4 ims.imscore.net
s=- s=-
c=IN IP4 203.0.113.1 c=IN IP4 203.0.113.1
t=0 0 t=0 0
m=audio PORT RTP/AVP 9 97 8 101 96 m=audio PORT RTP/AVP 9 111 8 101 96
a=rtpmap:9 G722/8000 a=rtpmap:9 G722/8000
a=rtpmap:97 opus/48000 a=rtpmap:111 opus/48000
a=rtpmap:8 PCMA/8000 a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/48000 a=rtpmap:101 telephone-event/48000
a=fmtp:101 0-15 a=fmtp:101 0-15

@ -105,11 +105,11 @@ static void __ht_set(GHashTable *h, char *x) {
#define sdp_pt_fmt(num, codec, clockrate, fmt) \ #define sdp_pt_fmt(num, codec, clockrate, fmt) \
__sdp_pt_fmt(num, (str) STR_CONST_INIT(#codec), clockrate, (str) STR_CONST_INIT(#codec "/" #clockrate), \ __sdp_pt_fmt(num, (str) STR_CONST_INIT(#codec), clockrate, (str) STR_CONST_INIT(#codec "/" #clockrate), \
(str) STR_CONST_INIT(fmt)) (str) STR_CONST_INIT(#codec "/" #clockrate "/1"), (str) STR_CONST_INIT(fmt))
static void __sdp_pt_fmt(int num, str codec, int clockrate, str full_codec, str fmt) { static void __sdp_pt_fmt(int num, str codec, int clockrate, str full_codec, str full_full, str fmt) {
struct rtp_payload_type *pt = g_slice_alloc(sizeof(*pt)); struct rtp_payload_type *pt = g_slice_alloc(sizeof(*pt));
*pt = (struct rtp_payload_type) { num, full_codec, codec, *pt = (struct rtp_payload_type) { num, full_codec, full_full, codec,
clockrate, STR_CONST_INIT(""), 1, fmt, {0,0}, {0,0}, 0, 0, NULL }; clockrate, STR_CONST_INIT(""), 1, fmt, {0,0}, {0,0}, 0, 0, NULL };
g_queue_push_tail(&rtp_types, pt); g_queue_push_tail(&rtp_types, pt);
} }

Loading…
Cancel
Save