summaryrefslogtreecommitdiff
path: root/main/translate.c
diff options
context:
space:
mode:
authorAlexander Traud <pabstraud@compuserve.com>2015-11-11 13:29:24 +0100
committerAlexander Traud <pabstraud@compuserve.com>2015-11-19 10:47:31 +0100
commit8ccb1d2bed90629c8755b362ee6850ef9586be14 (patch)
tree68d36d3ba68764aeea2c87de9f3c1fb08395af5c /main/translate.c
parente4af14784ee086397e8400571b8ec551cb9d544f (diff)
translate: Provide translation modules the result of SDP negotiation.
Previously, a trancoding module did not have access to the joint but cached format. Therefore, the module did not have access to the attributes negotiated via SDP (line fmtp). Now, a translation module receives the joint format. ASTERISK-25545 #close Change-Id: Id6878a989b50573298dab115d3371ea369e1a718
Diffstat (limited to 'main/translate.c')
-rw-r--r--main/translate.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/main/translate.c b/main/translate.c
index 334d3b550..61a827b71 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -298,6 +298,10 @@ static void destroy(struct ast_trans_pvt *pvt)
t->destroy(pvt);
}
ao2_cleanup(pvt->f.subclass.format);
+ if (pvt->explicit_dst) {
+ ao2_ref(pvt->explicit_dst, -1);
+ pvt->explicit_dst = NULL;
+ }
ast_free(pvt);
ast_module_unref(t->module);
}
@@ -306,7 +310,7 @@ static void destroy(struct ast_trans_pvt *pvt)
* \brief Allocate the descriptor, required outbuf space,
* and possibly desc.
*/
-static struct ast_trans_pvt *newpvt(struct ast_translator *t)
+static struct ast_trans_pvt *newpvt(struct ast_translator *t, struct ast_format *explicit_dst)
{
struct ast_trans_pvt *pvt;
int len;
@@ -332,6 +336,12 @@ static struct ast_trans_pvt *newpvt(struct ast_translator *t)
if (t->buf_size) {/* finally buffer and header */
pvt->outbuf.c = ofs + AST_FRIENDLY_OFFSET;
}
+ /*
+ * If the format has an attribute module, explicit_dst includes the (joined)
+ * result of the SDP negotiation. For example with the Opus Codec, the format
+ * knows whether both parties want to do forward-error correction (FEC).
+ */
+ pvt->explicit_dst = ao2_bump(explicit_dst);
ast_module_ref(t->module);
@@ -349,9 +359,16 @@ static struct ast_trans_pvt *newpvt(struct ast_translator *t)
pvt->f.src = pvt->t->name;
pvt->f.data.ptr = pvt->outbuf.c;
- /* if the translator has not provided a format find one in the cache or create one */
+ /*
+ * If the translator has not provided a format
+ * A) use the joined one,
+ * B) use the cached one, or
+ * C) create one.
+ */
if (!pvt->f.subclass.format) {
- if (!ast_strlen_zero(pvt->t->format)) {
+ pvt->f.subclass.format = ao2_bump(pvt->explicit_dst);
+
+ if (!pvt->f.subclass.format && !ast_strlen_zero(pvt->t->format)) {
pvt->f.subclass.format = ast_format_cache_get(pvt->t->format);
}
@@ -477,6 +494,7 @@ struct ast_trans_pvt *ast_translator_build_path(struct ast_format *dst, struct a
while (src_index != dst_index) {
struct ast_trans_pvt *cur;
+ struct ast_format *explicit_dst = NULL;
struct ast_translator *t = matrix_get(src_index, dst_index)->step;
if (!t) {
ast_log(LOG_WARNING, "No translator path from %s to %s\n",
@@ -484,7 +502,10 @@ struct ast_trans_pvt *ast_translator_build_path(struct ast_format *dst, struct a
AST_RWLIST_UNLOCK(&translators);
return NULL;
}
- if (!(cur = newpvt(t))) {
+ 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)))) {
+ explicit_dst = dst;
+ }
+ if (!(cur = newpvt(t, explicit_dst))) {
ast_log(LOG_WARNING, "Failed to build translator step from %s to %s\n",
ast_format_get_name(src), ast_format_get_name(dst));
if (head) {
@@ -638,7 +659,7 @@ static void generate_computational_cost(struct ast_translator *t, int seconds)
return;
}
- pvt = newpvt(t);
+ pvt = newpvt(t, NULL);
if (!pvt) {
ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
t->comp_cost = 999999;