summaryrefslogtreecommitdiff
path: root/modules/amr
diff options
context:
space:
mode:
authorAlfred E. Heggestad <aeh@db.org>2015-06-14 12:05:01 +0200
committerAlfred E. Heggestad <aeh@db.org>2015-06-14 12:05:01 +0200
commit2753cdfc7c3574a2d32f5b251cb857027074d3d7 (patch)
tree2e24aaf5044a9e721cdd82289020be46ca656fd7 /modules/amr
parente347c366253d74ffcd282c6c76e2f459f8ea7714 (diff)
amr: add support for octet-align mode
- this fixes compliance with RFC 4867 - this will break interop with older versions of baresip - Bandwidth-Efficient Mode can be added later fixes issue #37
Diffstat (limited to 'modules/amr')
-rw-r--r--modules/amr/amr.c30
-rw-r--r--modules/amr/amr.h10
-rw-r--r--modules/amr/module.mk2
-rw-r--r--modules/amr/sdp.c56
4 files changed, 88 insertions, 10 deletions
diff --git a/modules/amr/amr.c b/modules/amr/amr.c
index 1e698d1..74e353a 100644
--- a/modules/amr/amr.c
+++ b/modules/amr/amr.c
@@ -17,6 +17,7 @@
#endif
#include <re.h>
#include <baresip.h>
+#include "amr.h"
#ifdef VO_AMRWBENC_ENC_IF_H
@@ -25,10 +26,15 @@
#endif
-/*
+/**
+ * @defgroup amr amr
+ *
* This module supports both AMR Narrowband (8000 Hz) and
* AMR Wideband (16000 Hz) audio codecs.
*
+ * NOTE: only octet-align mode is supported.
+ *
+ *
* Reference:
*
* http://tools.ietf.org/html/rfc4867
@@ -209,11 +215,14 @@ static int encode_wb(struct auenc_state *st, uint8_t *buf, size_t *len,
if (*len < NB_SERIAL_MAX)
return ENOMEM;
- n = IF2E_IF_encode(st->enc, 8, sampv, buf, 0);
+ /* CMR value 15 indicates that no mode request is present */
+ buf[0] = 15 << 4;
+
+ n = IF2E_IF_encode(st->enc, 8, sampv, &buf[1], 0);
if (n <= 0)
return EPROTO;
- *len = n;
+ *len = (1 + n);
return 0;
}
@@ -227,7 +236,7 @@ static int decode_wb(struct audec_state *st, int16_t *sampv, size_t *sampc,
if (len > NB_SERIAL_MAX)
return EINVAL;
- IF2D_IF_decode(st->dec, buf, sampv, 0);
+ IF2D_IF_decode(st->dec, &buf[1], sampv, 0);
*sampc = L_FRAME16k;
@@ -247,11 +256,14 @@ static int encode_nb(struct auenc_state *st, uint8_t *buf,
if (*len < NB_SERIAL_MAX)
return ENOMEM;
- r = Encoder_Interface_Encode(st->enc, MR475, sampv, buf, 0);
+ /* CMR value 15 indicates that no mode request is present */
+ buf[0] = 15 << 4;
+
+ r = Encoder_Interface_Encode(st->enc, MR122, sampv, &buf[1], 0);
if (r <= 0)
return EPROTO;
- *len = r;
+ *len = (1 + r);
return 0;
}
@@ -269,7 +281,7 @@ static int decode_nb(struct audec_state *st, int16_t *sampv,
if (*sampc < L_FRAME16k)
return ENOMEM;
- Decoder_Interface_Decode(st->dec, buf, sampv, 0);
+ Decoder_Interface_Decode(st->dec, &buf[1], sampv, 0);
*sampc = FRAMESIZE_NB;
@@ -283,7 +295,7 @@ static struct aucodec amr_wb = {
LE_INIT, NULL, "AMR-WB", 16000, 1, NULL,
encode_update, encode_wb,
decode_update, decode_wb,
- NULL, NULL, NULL
+ NULL, amr_fmtp_enc, amr_fmtp_cmp
};
#endif
#ifdef AMR_NB
@@ -291,7 +303,7 @@ static struct aucodec amr_nb = {
LE_INIT, NULL, "AMR", 8000, 1, NULL,
encode_update, encode_nb,
decode_update, decode_nb,
- NULL, NULL, NULL
+ NULL, amr_fmtp_enc, amr_fmtp_cmp
};
#endif
diff --git a/modules/amr/amr.h b/modules/amr/amr.h
new file mode 100644
index 0000000..6746a83
--- /dev/null
+++ b/modules/amr/amr.h
@@ -0,0 +1,10 @@
+/**
+ * @file amr/amr.h AMR module -- internal interface
+ *
+ * Copyright (C) 2010 - 2015 Creytiv.com
+ */
+
+
+int amr_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt,
+ bool offer, void *arg);
+bool amr_fmtp_cmp(const char *lfmtp, const char *rfmtp, void *arg);
diff --git a/modules/amr/module.mk b/modules/amr/module.mk
index cbe1013..4f8ecdf 100644
--- a/modules/amr/module.mk
+++ b/modules/amr/module.mk
@@ -5,7 +5,7 @@
#
MOD := amr
-$(MOD)_SRCS += amr.c
+$(MOD)_SRCS += amr.c sdp.c
ifneq ($(shell [ -d $(SYSROOT)/include/opencore-amrnb ] && echo 1 ),)
diff --git a/modules/amr/sdp.c b/modules/amr/sdp.c
new file mode 100644
index 0000000..e4b0cdf
--- /dev/null
+++ b/modules/amr/sdp.c
@@ -0,0 +1,56 @@
+/**
+ * @file amr/sdp.c AMR SDP Functions
+ *
+ * Copyright (C) 2010 - 2015 Creytiv.com
+ */
+
+#include <re.h>
+#include <baresip.h>
+#include "amr.h"
+
+
+static bool amr_octet_align(const char *fmtp)
+{
+ struct pl pl, oa;
+
+ if (!fmtp)
+ return false;
+
+ pl_set_str(&pl, fmtp);
+
+ if (fmt_param_get(&pl, "octet-align", &oa))
+ return 0 == pl_strcmp(&oa, "1");
+
+ return false;
+}
+
+
+int amr_fmtp_enc(struct mbuf *mb, const struct sdp_format *fmt,
+ bool offer, void *arg)
+{
+ const struct aucodec *ac = arg;
+ (void)offer;
+
+ if (!mb || !fmt || !ac)
+ return 0;
+
+ return mbuf_printf(mb, "a=fmtp:%s octet-align=1\r\n",
+ fmt->id);
+}
+
+
+bool amr_fmtp_cmp(const char *lfmtp, const char *rfmtp, void *arg)
+{
+ const struct aucodec *ac = arg;
+ (void)lfmtp;
+
+ if (!ac)
+ return false;
+
+ if (!amr_octet_align(rfmtp)) {
+ info("amr: octet-align mode is required\n");
+ return false;
+ }
+
+ return true;
+}