diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/codec_builtin.c | 63 | ||||
-rw-r--r-- | main/features.c | 1 | ||||
-rw-r--r-- | main/format_cache.c | 20 | ||||
-rw-r--r-- | main/pbx.c | 19 | ||||
-rw-r--r-- | main/rtp_engine.c | 10 | ||||
-rw-r--r-- | main/stasis_endpoints.c | 34 | ||||
-rw-r--r-- | main/threadpool.c | 6 | ||||
-rw-r--r-- | main/translate.c | 2 |
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))) { |