From 2753cdfc7c3574a2d32f5b251cb857027074d3d7 Mon Sep 17 00:00:00 2001 From: "Alfred E. Heggestad" Date: Sun, 14 Jun 2015 12:05:01 +0200 Subject: 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 --- modules/amr/amr.c | 30 ++++++++++++++++++--------- modules/amr/amr.h | 10 +++++++++ modules/amr/module.mk | 2 +- modules/amr/sdp.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 modules/amr/amr.h create mode 100644 modules/amr/sdp.c (limited to 'modules/amr') 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 #include +#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 +#include +#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; +} -- cgit v1.2.3