diff options
author | Mark Michelson <mmichelson@digium.com> | 2016-06-30 15:58:53 -0500 |
---|---|---|
committer | Mark Michelson <mmichelson@digium.com> | 2016-07-14 15:54:21 -0500 |
commit | 28501051b47e6bb8968bb016abf0b3493c05fa21 (patch) | |
tree | 3d7f0e5fbe9f46e37e3033f7dbc44736e42a32ac /main | |
parent | 43a78100c0e51117e7e5c91ed2800c772f767f8a (diff) |
Update support for SILK format.
This commit adds scaffolding in order to support the SILK audio format
on calls. Roughly, this is what is added:
* Cached silk formats. One for each possible sample rate.
* ast_codec structures for each possible sample rate.
* RTP payload mappings for "SILK".
In addition, this change overhauls the res_format_attr_silk file in the
following ways:
* The "samplerate" attribute is scrapped. That's native to the format.
* There are far more checks to ensure that attributes have been
allocated before attempting to reference them.
* We do not SDP fmtp lines for attributes set to 0.
These changes make way to be able to install a codec_silk module and
have it actually work. It also should allow for passthrough silk calls
in Asterisk.
Change-Id: Ieeb39c95a9fecc9246bcfd3c45a6c9b51c59380e
Diffstat (limited to 'main')
-rw-r--r-- | main/codec_builtin.c | 63 | ||||
-rw-r--r-- | main/format_cache.c | 20 | ||||
-rw-r--r-- | main/rtp_engine.c | 10 |
3 files changed, 93 insertions, 0 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/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/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; } |