Browse Source

TT#91003 support `=` escapes in codec strings

Change-Id: Id974f40e12b33e1f299fac15e25decd741c98fb3
pull/1077/head
Richard Fuchs 5 years ago
parent
commit
25609f74da
3 changed files with 24 additions and 15 deletions
  1. +4
    -0
      README.md
  2. +17
    -7
      daemon/call_interfaces.c
  3. +3
    -8
      daemon/codec.c

+ 4
- 0
README.md View File

@ -1100,6 +1100,10 @@ Optionally included keys are:
Additional options that can be appended to the codec string with additional slashes
are ptime and the `fmtp` string, for example `iLBC/8000/1///mode=30`.
If a literal `=` cannot be used due to parsing constraints (i.e. being wrongly
interpreted as a key-value pair), it can be escaped by using two dashes instead,
e.g. `iLBC/8000/1///mode--30`.
As a special case, if the `strip=all` option has been used and the `transcode`
option is used on a codec that was originally present in the offer, then
*rtpengine* will treat this codec the same as if it had been used with the `offer`


+ 17
- 7
daemon/call_interfaces.c View File

@ -704,25 +704,35 @@ static void call_ng_flags_supports(struct sdp_ng_flags *out, str *s, void *dummy
if (!str_cmp(s, "load limit"))
out->supports_load_limit = 1;
}
static str *str_dup_escape(const str *s) {
str *ret = str_dup(s);
int i;
while ((i = str_str(ret, "--")) >= 0) {
ret->s[i] = '=';
memmove(&ret->s[i + 1], &ret->s[i + 2], ret->len - i - 2);
ret->len--;
}
return ret;
}
static void call_ng_flags_codec_list(struct sdp_ng_flags *out, str *s, void *qp) {
str *s_copy = str_slice_dup(s);
str *s_copy = str_dup_escape(s);
g_queue_push_tail((GQueue *) qp, s_copy);
}
static void call_ng_flags_str_ht(struct sdp_ng_flags *out, str *s, void *htp) {
str *s_copy = str_slice_dup(s);
str *s_copy = str_dup_escape(s);
GHashTable **ht = htp;
if (!*ht)
*ht = g_hash_table_new_full(str_case_hash, str_case_equal, str_slice_free, NULL);
*ht = g_hash_table_new_full(str_case_hash, str_case_equal, free, NULL);
g_hash_table_replace(*ht, s_copy, s_copy);
}
#ifdef WITH_TRANSCODING
static void call_ng_flags_str_ht_split(struct sdp_ng_flags *out, str *s, void *htp) {
GHashTable **ht = htp;
if (!*ht)
*ht = g_hash_table_new_full(str_case_hash, str_case_equal, str_slice_free, str_slice_free);
*ht = g_hash_table_new_full(str_case_hash, str_case_equal, free, free);
str splitter = *s;
while (1) {
g_hash_table_replace(*ht, str_slice_dup(&splitter), str_slice_dup(s));
g_hash_table_replace(*ht, str_dup_escape(&splitter), str_dup_escape(s));
char *c = memrchr(splitter.s, '/', splitter.len);
if (!c)
break;
@ -1009,8 +1019,8 @@ static void call_ng_free_flags(struct sdp_ng_flags *flags) {
g_hash_table_destroy(flags->codec_set);
if (flags->sdes_no)
g_hash_table_destroy(flags->sdes_no);
g_queue_clear_full(&flags->codec_offer, str_slice_free);
g_queue_clear_full(&flags->codec_transcode, str_slice_free);
g_queue_clear_full(&flags->codec_offer, free);
g_queue_clear_full(&flags->codec_transcode, free);
}
static enum load_limit_reasons call_offer_session_limit(void) {


+ 3
- 8
daemon/codec.c View File

@ -2129,7 +2129,6 @@ static int __codec_synth_transcode_options(struct rtp_payload_type *pt, struct s
if (pt->clock_rate != 1)
return 0;
struct call *call = media->call;
GHashTable *clockrates = g_hash_table_new(g_direct_hash, g_direct_equal);
// special handling - add one instance for each clock rate that is present
@ -2137,17 +2136,13 @@ static int __codec_synth_transcode_options(struct rtp_payload_type *pt, struct s
struct rtp_payload_type *pt_r = k->data;
if (g_hash_table_lookup(clockrates, GUINT_TO_POINTER(pt_r->clock_rate)))
continue;
char *pt_s;
if (asprintf(&pt_s, STR_FORMAT "/%u", STR_FMT(&pt->encoding), pt_r->clock_rate) < 0)
continue;
pt_s = call_strdup(call, pt_s);
// XXX optimise this -^ call buffer can probably be replaced with a gstringchunk
// and made lock free
char *pt_s = g_strdup_printf(STR_FORMAT "/%u", STR_FMT(&pt->encoding), pt_r->clock_rate);
g_hash_table_insert(clockrates, GUINT_TO_POINTER(pt_r->clock_rate), (void *) 1);
str pt_str;
str_init(&pt_str, pt_s);
ilog(LOG_DEBUG, "Synthesised transcoding option for '%s'", pt_s);
g_queue_push_tail(&flags->codec_transcode, str_slice_dup(&pt_str));
g_queue_push_tail(&flags->codec_transcode, str_dup(&pt_str));
g_free(pt_s);
}
payload_type_free(pt);


Loading…
Cancel
Save