mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user