From 2f5d792aaeb41c268c11cc1c41710a054189537e Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 14 May 2018 10:17:21 -0400 Subject: [PATCH] TT#36301 add `always-transcode` flag closes #527 Change-Id: I0d8192cf93c49823f35a6307ccd8c77842fb51dd --- README.md | 12 ++++++++++++ daemon/call.c | 2 +- daemon/call_interfaces.c | 2 ++ daemon/call_interfaces.h | 1 + daemon/codec.c | 9 +++++++-- daemon/codec.h | 3 ++- daemon/redis.c | 2 +- utils/rtpengine-ng-client | 3 ++- 8 files changed, 28 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bf4ab1e6f..11b5bf0ab 100644 --- a/README.md +++ b/README.md @@ -1176,6 +1176,18 @@ Optionally included keys are: attribute already present in the SDP, it will leave the SDP untouched and not process the message. + - `always transcode` + + When transcoding is in use, *rtpengine* will normally match up the codecs offered with + one side with the codecs offered by the other side, and engage the transcoding engine + only for codec pairs that are not supported by both sides. With this flag present, + *rtpengine* will skip the codec match-up routine and always trancode any received media + to the first (highest priority) codec offered by the other side that is supported for + transcoding. Using this flag engages the transcoding engine even if no other + `transcoding` flags are present. Unlike other transcoding options, this one is directional, + which means that it's applied only to the one side doing the signalling that is being + handled (i.e. the side doing the `offer` or the `answer`). + * `replace` Similar to the `flags` list. Controls which parts of the SDP body should be rewritten. diff --git a/daemon/call.c b/daemon/call.c index 8852e8e36..f0a87ff6b 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -1653,7 +1653,7 @@ int monologue_offer_answer(struct call_monologue *other_ml, GQueue *streams, codec_rtp_payload_types(media, other_media, &sp->rtp_payload_types, flags->codec_strip, &flags->codec_offer, &flags->codec_transcode, flags->codec_mask); - codec_handlers_update(media, other_media); + codec_handlers_update(media, other_media, flags); /* send and recv are from our POV */ bf_copy_same(&media->media_flags, &sp->sp_flags, diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 3722f127f..ce9693405 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -616,6 +616,8 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) { out->no_rtcp_attr = 1; else if (!str_cmp(s, "loop-protect")) out->loop_protect = 1; + else if (!str_cmp(s, "always-transcode")) + out->always_transcode = 1; else { // handle values aliases from other dictionaries if (call_ng_flags_prefix(out, s, "SDES-", ng_sdes_option, NULL)) diff --git a/daemon/call_interfaces.h b/daemon/call_interfaces.h index b91ed6230..a59eea1e1 100644 --- a/daemon/call_interfaces.h +++ b/daemon/call_interfaces.h @@ -59,6 +59,7 @@ struct sdp_ng_flags { reset:1, record_call:1, loop_protect:1, + always_transcode:1, supports_load_limit:1, dtls_off:1, sdes_off:1, diff --git a/daemon/codec.c b/daemon/codec.c index 1469cc6e8..0660d2be1 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -9,6 +9,7 @@ #include "codeclib.h" #include "ssrc.h" #include "rtcp.h" +#include "call_interfaces.h" @@ -158,7 +159,9 @@ static GList *__delete_receiver_codec(struct call_media *receiver, GList *link) } // call must be locked in W -void codec_handlers_update(struct call_media *receiver, struct call_media *sink) { +void codec_handlers_update(struct call_media *receiver, struct call_media *sink, + const struct sdp_ng_flags *flags) +{ if (!receiver->codec_handlers) receiver->codec_handlers = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, __codec_handler_free); @@ -302,7 +305,9 @@ void codec_handlers_update(struct call_media *receiver, struct call_media *sink) // in case of ptime mismatch, we transcode //struct rtp_payload_type *dest_pt = g_hash_table_lookup(sink->codec_names_send, &pt->encoding); - GQueue *dest_codecs = g_hash_table_lookup(sink->codec_names_send, &pt->encoding); + GQueue *dest_codecs = NULL; + if (!flags || !flags->always_transcode) + dest_codecs = g_hash_table_lookup(sink->codec_names_send, &pt->encoding); if (dest_codecs) { // the sink supports this codec - check offered formats dest_pt = NULL; diff --git a/daemon/codec.h b/daemon/codec.h index 945baaac2..83ed9259f 100644 --- a/daemon/codec.h +++ b/daemon/codec.h @@ -13,6 +13,7 @@ struct call_media; struct codec_handler; struct media_packet; struct ssrc_hash; +struct sdp_ng_flags; typedef int codec_handler_func(struct codec_handler *, struct call_media *, struct media_packet *); @@ -56,7 +57,7 @@ void __rtp_payload_type_add_send(struct call_media *other_media, struct rtp_payl #ifdef WITH_TRANSCODING -void codec_handlers_update(struct call_media *receiver, struct call_media *sink); +void codec_handlers_update(struct call_media *receiver, struct call_media *sink, const struct sdp_ng_flags *); #else diff --git a/daemon/redis.c b/daemon/redis.c index f90183348..9beee0a04 100644 --- a/daemon/redis.c +++ b/daemon/redis.c @@ -1413,7 +1413,7 @@ static int json_link_medias(struct call *c, struct redis_list *medias, for (GList *l = other_ml->medias.head; l; l = l->next) { struct call_media *other_m = l->data; if (other_m->index == med->index) { - codec_handlers_update(med, other_m); + codec_handlers_update(med, other_m, NULL); break; } } diff --git a/utils/rtpengine-ng-client b/utils/rtpengine-ng-client index bf798d8f5..8cfd4ffa5 100755 --- a/utils/rtpengine-ng-client +++ b/utils/rtpengine-ng-client @@ -56,6 +56,7 @@ GetOptions( 'flags=s@' => \$options{'flags'}, 'supports=s@' => \$options{'supports'}, 'xmlrpc-callback=s' => \$options{'xmlrpc-callback'}, + 'always-transcode' => \$options{'always transcode'}, ) or die; my $cmd = shift(@ARGV) or die; @@ -68,7 +69,7 @@ for my $x (split(/,/, 'from-tag,to-tag,call-id,transport protocol,media address, for my $x (split(/,/, 'TOS,delete-delay')) { defined($options{$x}) and $packet{$x} = $options{$x}; } -for my $x (split(/,/, 'trust address,symmetric,asymmetric,force,strict source,media handover,sip source address,reset,port latching,no rtcp attribute,loop protect,record call')) { +for my $x (split(/,/, 'trust address,symmetric,asymmetric,force,strict source,media handover,sip source address,reset,port latching,no rtcp attribute,loop protect,record call,always transcode')) { defined($options{$x}) and push(@{$packet{flags}}, $x); } for my $x (split(/,/, 'origin,session connection')) {