summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/codec_builtin.c63
-rw-r--r--main/features.c1
-rw-r--r--main/format_cache.c20
-rw-r--r--main/pbx.c19
-rw-r--r--main/rtp_engine.c10
-rw-r--r--main/stasis_endpoints.c34
-rw-r--r--main/threadpool.c6
-rw-r--r--main/translate.c2
8 files changed, 135 insertions, 20 deletions
diff --git a/main/codec_builtin.c b/main/codec_builtin.c
index d3f65174c..1d329bc3b 100644
--- a/main/codec_builtin.c
+++ b/main/codec_builtin.c
@@ -772,6 +772,65 @@ static struct ast_codec t140 = {
.type = AST_MEDIA_TYPE_TEXT,
};
+static int silk_samples(struct ast_frame *frame)
+{
+ /* XXX This is likely not at all what's intended from this callback. However,
+ * since SILK is variable bit rate, I have no idea how to take a frame of data
+ * and determine the number of samples present. Instead, we base this on the
+ * sample rate of the codec and the expected number of samples to receive in 20ms.
+ * In testing, this has worked just fine.
+ */
+ return ast_format_get_sample_rate(frame->subclass.format) / 50;
+}
+
+static struct ast_codec silk8 = {
+ .name = "silk",
+ .description = "SILK Codec (8 KHz)",
+ .type = AST_MEDIA_TYPE_AUDIO,
+ .sample_rate = 8000,
+ .minimum_ms = 20,
+ .maximum_ms = 100,
+ .default_ms = 20,
+ .minimum_bytes = 160,
+ .samples_count = silk_samples
+};
+
+static struct ast_codec silk12 = {
+ .name = "silk",
+ .description = "SILK Codec (12 KHz)",
+ .type = AST_MEDIA_TYPE_AUDIO,
+ .sample_rate = 12000,
+ .minimum_ms = 20,
+ .maximum_ms = 100,
+ .default_ms = 20,
+ .minimum_bytes = 240,
+ .samples_count = silk_samples
+};
+
+static struct ast_codec silk16 = {
+ .name = "silk",
+ .description = "SILK Codec (16 KHz)",
+ .type = AST_MEDIA_TYPE_AUDIO,
+ .sample_rate = 16000,
+ .minimum_ms = 20,
+ .maximum_ms = 100,
+ .default_ms = 20,
+ .minimum_bytes = 320,
+ .samples_count = silk_samples
+};
+
+static struct ast_codec silk24 = {
+ .name = "silk",
+ .description = "SILK Codec (24 KHz)",
+ .type = AST_MEDIA_TYPE_AUDIO,
+ .sample_rate = 24000,
+ .minimum_ms = 20,
+ .maximum_ms = 100,
+ .default_ms = 20,
+ .minimum_bytes = 480,
+ .samples_count = silk_samples
+};
+
#define CODEC_REGISTER_AND_CACHE(codec) \
({ \
int __res_ ## __LINE__ = 0; \
@@ -843,6 +902,10 @@ int ast_codec_builtin_init(void)
res |= CODEC_REGISTER_AND_CACHE(t140red);
res |= CODEC_REGISTER_AND_CACHE(t140);
res |= CODEC_REGISTER_AND_CACHE(none);
+ res |= CODEC_REGISTER_AND_CACHE_NAMED("silk8", silk8);
+ res |= CODEC_REGISTER_AND_CACHE_NAMED("silk12", silk12);
+ res |= CODEC_REGISTER_AND_CACHE_NAMED("silk16", silk16);
+ res |= CODEC_REGISTER_AND_CACHE_NAMED("silk24", silk24);
return res;
}
diff --git a/main/features.c b/main/features.c
index 00010514c..43ec5e1c6 100644
--- a/main/features.c
+++ b/main/features.c
@@ -64,7 +64,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/cli.h"
#include "asterisk/manager.h"
#include "asterisk/utils.h"
-#include "asterisk/adsi.h"
#include "asterisk/devicestate.h"
#include "asterisk/audiohook.h"
#include "asterisk/global_datastores.h"
diff --git a/main/format_cache.c b/main/format_cache.c
index 6638a78c0..74ebfe8d5 100644
--- a/main/format_cache.c
+++ b/main/format_cache.c
@@ -232,6 +232,14 @@ struct ast_format *ast_format_t140_red;
*/
struct ast_format *ast_format_none;
+/*!
+ * \brief Built-in "silk" format
+ */
+struct ast_format *ast_format_silk8;
+struct ast_format *ast_format_silk12;
+struct ast_format *ast_format_silk16;
+struct ast_format *ast_format_silk24;
+
/*! \brief Number of buckets to use for the media format cache (should be prime for performance reasons) */
#define CACHE_BUCKETS 53
@@ -331,6 +339,10 @@ static void format_cache_shutdown(void)
ao2_replace(ast_format_t140_red, NULL);
ao2_replace(ast_format_t140, NULL);
ao2_replace(ast_format_none, NULL);
+ ao2_replace(ast_format_silk8, NULL);
+ ao2_replace(ast_format_silk12, NULL);
+ ao2_replace(ast_format_silk16, NULL);
+ ao2_replace(ast_format_silk24, NULL);
}
int ast_format_cache_init(void)
@@ -426,6 +438,14 @@ static void set_cached_format(const char *name, struct ast_format *format)
ao2_replace(ast_format_t140, format);
} else if (!strcmp(name, "none")) {
ao2_replace(ast_format_none, format);
+ } else if (!strcmp(name, "silk8")) {
+ ao2_replace(ast_format_silk8, format);
+ } else if (!strcmp(name, "silk12")) {
+ ao2_replace(ast_format_silk12, format);
+ } else if (!strcmp(name, "silk16")) {
+ ao2_replace(ast_format_silk16, format);
+ } else if (!strcmp(name, "silk24")) {
+ ao2_replace(ast_format_silk24, format);
}
}
diff --git a/main/pbx.c b/main/pbx.c
index 6b0069c06..5bafee337 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -4682,6 +4682,13 @@ static struct ast_context *find_context_locked(const char *context)
return c;
}
+/*! \brief Free an ast_include and associated data. */
+static void include_free(struct ast_include *include)
+{
+ ast_destroy_timing(&(include->timing));
+ ast_free(include);
+}
+
/*!
* \brief Remove included contexts.
* This function locks contexts list by &conlist, search for the right context
@@ -4729,8 +4736,7 @@ int ast_context_remove_include2(struct ast_context *con, const char *include, co
else
con->includes = i->next;
/* free include and return */
- ast_destroy_timing(&(i->timing));
- ast_free(i);
+ include_free(i);
ret = 0;
break;
}
@@ -6481,8 +6487,7 @@ int ast_context_add_include2(struct ast_context *con, const char *value,
/* ... go to last include and check if context is already included too... */
for (i = con->includes; i; i = i->next) {
if (!strcasecmp(i->name, new_include->name)) {
- ast_destroy_timing(&(new_include->timing));
- ast_free(new_include);
+ include_free(new_include);
ast_unlock_context(con);
errno = EEXIST;
return -1;
@@ -7706,7 +7711,7 @@ static void __ast_internal_context_destroy( struct ast_context *con)
for (tmpi = tmp->includes; tmpi; ) { /* Free includes */
struct ast_include *tmpil = tmpi;
tmpi = tmpi->next;
- ast_free(tmpil);
+ include_free(tmpil);
}
for (ipi = tmp->ignorepats; ipi; ) { /* Free ignorepats */
struct ast_ignorepat *ipl = ipi;
@@ -7800,12 +7805,12 @@ void __ast_context_destroy(struct ast_context *list, struct ast_hashtab *context
if (pi) {
pi->next = i->next;
/* free include */
- ast_free(i);
+ include_free(i);
continue; /* don't change pi */
} else {
tmp->includes = i->next;
/* free include */
- ast_free(i);
+ include_free(i);
continue; /* don't change pi */
}
}
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 462d4c530..8d46bfdcc 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -2198,6 +2198,11 @@ int ast_rtp_engine_init(void)
/* Opus and VP8 */
set_next_mime_type(ast_format_opus, 0, "audio", "opus", 48000);
set_next_mime_type(ast_format_vp8, 0, "video", "VP8", 90000);
+ /* DA SILK */
+ set_next_mime_type(ast_format_silk8, 0, "audio", "silk", 8000);
+ set_next_mime_type(ast_format_silk12, 0, "audio", "silk", 12000);
+ set_next_mime_type(ast_format_silk16, 0, "audio", "silk", 16000);
+ set_next_mime_type(ast_format_silk24, 0, "audio", "silk", 24000);
/* Define the static rtp payload mappings */
add_static_payload(0, ast_format_ulaw, 0);
@@ -2243,6 +2248,11 @@ int ast_rtp_engine_init(void)
add_static_payload(100, ast_format_vp8, 0);
add_static_payload(107, ast_format_opus, 0);
+ add_static_payload(108, ast_format_silk8, 0);
+ add_static_payload(109, ast_format_silk12, 0);
+ add_static_payload(113, ast_format_silk16, 0);
+ add_static_payload(114, ast_format_silk24, 0);
+
return 0;
}
diff --git a/main/stasis_endpoints.c b/main/stasis_endpoints.c
index c31714bf4..8cc60506c 100644
--- a/main/stasis_endpoints.c
+++ b/main/stasis_endpoints.c
@@ -253,6 +253,7 @@ static struct ast_json *contactstatus_to_json(struct stasis_message *msg, const
struct ast_endpoint_blob *obj = stasis_message_data(msg);
struct ast_json *json_endpoint;
struct ast_json *json_final;
+ const char *rtt;
const struct timeval *tv = stasis_message_timestamp(msg);
json_endpoint = ast_endpoint_snapshot_to_json(obj->snapshot, NULL);
@@ -260,15 +261,30 @@ static struct ast_json *contactstatus_to_json(struct stasis_message *msg, const
return NULL;
}
- json_final = ast_json_pack("{s: s, s: o, s: o, s: { s: s, s: s, s: s, s: s } } ",
- "type", "ContactStatusChange",
- "timestamp", ast_json_timeval(*tv, NULL),
- "endpoint", json_endpoint,
- "contact_info",
- "uri", ast_json_string_get(ast_json_object_get(obj->blob, "uri")),
- "contact_status", ast_json_string_get(ast_json_object_get(obj->blob, "contact_status")),
- "aor", ast_json_string_get(ast_json_object_get(obj->blob, "aor")),
- "roundtrip_usec", ast_json_string_get(ast_json_object_get(obj->blob, "roundtrip_usec")));
+ /* The roundtrip time is optional. */
+ rtt = ast_json_string_get(ast_json_object_get(obj->blob, "roundtrip_usec"));
+ if (!ast_strlen_zero(rtt)) {
+ json_final = ast_json_pack("{s: s, s: o, s: o, s: { s: s, s: s, s: s, s: s } } ",
+ "type", "ContactStatusChange",
+ "timestamp", ast_json_timeval(*tv, NULL),
+ "endpoint", json_endpoint,
+ "contact_info",
+ "uri", ast_json_string_get(ast_json_object_get(obj->blob, "uri")),
+ "contact_status", ast_json_string_get(ast_json_object_get(obj->blob,
+ "contact_status")),
+ "aor", ast_json_string_get(ast_json_object_get(obj->blob, "aor")),
+ "roundtrip_usec", rtt);
+ } else {
+ json_final = ast_json_pack("{s: s, s: o, s: o, s: { s: s, s: s, s: s } } ",
+ "type", "ContactStatusChange",
+ "timestamp", ast_json_timeval(*tv, NULL),
+ "endpoint", json_endpoint,
+ "contact_info",
+ "uri", ast_json_string_get(ast_json_object_get(obj->blob, "uri")),
+ "contact_status", ast_json_string_get(ast_json_object_get(obj->blob,
+ "contact_status")),
+ "aor", ast_json_string_get(ast_json_object_get(obj->blob, "aor")));
+ }
if (!json_final) {
ast_json_unref(json_endpoint);
}
diff --git a/main/threadpool.c b/main/threadpool.c
index 9cd33ab1a..6240b7329 100644
--- a/main/threadpool.c
+++ b/main/threadpool.c
@@ -1384,10 +1384,12 @@ struct ast_taskprocessor *ast_threadpool_serializer_group(const char *name,
ao2_ref(ser, -1);
return NULL;
}
- /* ser ref transferred to listener */
tps = ast_taskprocessor_create_with_listener(name, listener);
- if (tps && shutdown_group) {
+ if (!tps) {
+ /* ser ref transferred to listener but not cleaned without tps */
+ ao2_ref(ser, -1);
+ } else if (shutdown_group) {
serializer_shutdown_group_inc(shutdown_group);
}
diff --git a/main/translate.c b/main/translate.c
index 6a39bac1a..73e03a82e 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -494,7 +494,7 @@ struct ast_trans_pvt *ast_translator_build_path(struct ast_format *dst, struct a
AST_RWLIST_UNLOCK(&translators);
return NULL;
}
- if ((t->dst_codec.sample_rate == ast_format_get_sample_rate(dst)) && (t->dst_codec.type == ast_format_get_type(dst)) && (!strcmp(t->dst_codec.name, ast_format_get_name(dst)))) {
+ if ((t->dst_codec.sample_rate == ast_format_get_sample_rate(dst)) && (t->dst_codec.type == ast_format_get_type(dst))) {
explicit_dst = dst;
}
if (!(cur = newpvt(t, explicit_dst))) {