summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Joseph <gjoseph@digium.com>2016-07-23 13:50:37 -0600
committerKevin Harwell <kharwell@digium.com>2016-09-27 09:52:24 -0500
commita5af8709c8d3079191bd5caca77a800e9c446af2 (patch)
tree6690eab18e3fc06294515906f2e792adb185c1ba
parent44c0c51cf1c2c89326e5047b2b90ada0e36ec68f (diff)
codec_opus: Replace res_format_attr_opus with the one from codec_opus
Preparation ASTERISK-26409 Change-Id: I9f20e7cce00c32464d9a180e81283d49d199d0a3 (cherry picked from commit 59f7662a93bf9c07204fb50e1020a0f5bfbbd5c9)
-rw-r--r--include/asterisk/opus.h51
-rw-r--r--res/res_format_attr_opus.c348
2 files changed, 224 insertions, 175 deletions
diff --git a/include/asterisk/opus.h b/include/asterisk/opus.h
index 0fbcfa10e..6d2cdcf8c 100644
--- a/include/asterisk/opus.h
+++ b/include/asterisk/opus.h
@@ -18,24 +18,47 @@
/*!
* \file
- * \brief Opus Format Attributes (http://tools.ietf.org/html/draft-ietf-payload-rtp-opus)
+ * \brief Codec opus externals and format attributes
*
- * \author Lorenzo Miniero <lorenzo@meetecho.com>
+ * RFC - https://tools.ietf.org/rfc/rfc7587.txt
*/
#ifndef _AST_FORMAT_OPUS_H_
#define _AST_FORMAT_OPUS_H_
-/*! Opus format attribute key value pairs, all are accessible through ast_format_get_value()*/
-enum opus_attr_keys {
- OPUS_ATTR_KEY_MAX_BITRATE, /*! value is an int (6000-510000 in spec). */
- OPUS_ATTR_KEY_MAX_PLAYRATE, /*! value is an int (8000-48000), maximum output rate the receiver can render. */
- OPUS_ATTR_KEY_MINPTIME, /*! value is an int (3-120 in spec, 10-60 in format.c), decoder's minimum length of time in milliseconds. */
- OPUS_ATTR_KEY_STEREO, /*! value is an int, 1 prefer receiving stereo, 0 prefer mono. */
- OPUS_ATTR_KEY_CBR, /*! value is an int, 1 use constant bitrate, 0 use variable bitrate. */
- OPUS_ATTR_KEY_FEC, /*! value is an int, 1 encode with FEC, 0 do not use FEC. */
- OPUS_ATTR_KEY_DTX, /*! value is an int, 1 dtx is enabled, 0 dtx not enabled. */
- OPUS_ATTR_KEY_SPROP_CAPTURE_RATE, /*! value is an int (8000-48000), likely input rate we're going to produce. */
- OPUS_ATTR_KEY_SPROP_STEREO, /*! value is an int, 1 likely to send stereo, 0 likely to send mono. */
-};
+/*! \brief Maximum sampling rate an endpoint is capable of receiving */
+#define CODEC_OPUS_ATTR_MAX_PLAYBACK_RATE "maxplaybackrate"
+/*! \brief An alias for maxplaybackrate (used in older versions) */
+#define CODEC_OPUS_ATTR_MAX_CODED_AUDIO_BANDWIDTH "maxcodedaudiobandwidth"
+/*! \brief Maximum sampling rate an endpoint is capable of sending */
+#define CODEC_OPUS_ATTR_SPROP_MAX_CAPTURE_RATE "sprop-maxcapturerate"
+/*! \brief Maximum duration of packet (in milliseconds) */
+#define CODEC_OPUS_ATTR_MAX_PTIME "maxptime"
+/*! \brief Duration of packet (in milliseconds) */
+#define CODEC_OPUS_ATTR_PTIME "ptime"
+/*! \brief Maximum average received bit rate (in bits per second) */
+#define CODEC_OPUS_ATTR_MAX_AVERAGE_BITRATE "maxaveragebitrate"
+/*! \brief Decode stereo (1) vs mono (0) */
+#define CODEC_OPUS_ATTR_STEREO "stereo"
+/*! \brief Likeliness of sender producing stereo (1) vs mono (0) */
+#define CODEC_OPUS_ATTR_SPROP_STEREO "sprop-stereo"
+/*! \brief Decoder prefers a constant (1) vs variable (0) bitrate */
+#define CODEC_OPUS_ATTR_CBR "cbr"
+/*! \brief Use forward error correction (1) or not (0) */
+#define CODEC_OPUS_ATTR_FEC "useinbandfec"
+/*! \brief Use discontinuous transmission (1) or not (0) */
+#define CODEC_OPUS_ATTR_DTX "usedtx"
+/*! \brief Custom data object */
+#define CODEC_OPUS_ATTR_DATA "data"
+
+/*! \brief Default attribute values */
+#define CODEC_OPUS_DEFAULT_SAMPLE_RATE 48000
+#define CODEC_OPUS_DEFAULT_MAX_PLAYBACK_RATE 48000
+#define CODEC_OPUS_DEFAULT_MAX_PTIME 120
+#define CODEC_OPUS_DEFAULT_PTIME 20
+#define CODEC_OPUS_DEFAULT_BITRATE -1000 /* OPUS_AUTO */
+#define CODEC_OPUS_DEFAULT_CBR 0
+#define CODEC_OPUS_DEFAULT_FEC 0
+#define CODEC_OPUS_DEFAULT_DTX 0
+#define CODEC_OPUS_DEFAULT_STEREO 0
#endif /* _AST_FORMAT_OPUS_H */
diff --git a/res/res_format_attr_opus.c b/res/res_format_attr_opus.c
index 4e81df08a..12b910593 100644
--- a/res/res_format_attr_opus.c
+++ b/res/res_format_attr_opus.c
@@ -33,9 +33,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/module.h"
#include "asterisk/format.h"
-#include "asterisk/logger.h" /* for ast_log, LOG_WARNING */
-#include "asterisk/strings.h" /* for ast_str_append */
-#include "asterisk/utils.h" /* for MIN, ast_malloc, ast_free */
+#include "asterisk/logger.h"
+#include "asterisk/strings.h"
+#include "asterisk/utils.h"
+#include "asterisk/opus.h"
/*!
* \brief Opus attribute structure.
@@ -43,32 +44,42 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
* \note http://tools.ietf.org/html/rfc7587#section-6
*/
struct opus_attr {
- unsigned int maxbitrate;
- unsigned int maxplayrate;
- unsigned int unused; /* was minptime, kept for binary compatibility */
- unsigned int stereo;
- unsigned int cbr;
- unsigned int fec;
- unsigned int dtx;
- unsigned int spropmaxcapturerate;
- unsigned int spropstereo;
+ int maxbitrate;
+ int maxplayrate;
+ int ptime;
+ int stereo;
+ int cbr;
+ int fec;
+ int dtx;
+ int spropmaxcapturerate;
+ int spropstereo;
+ int maxptime;
+ /* Note data is expected to be an ao2_object type */
+ void *data;
};
static struct opus_attr default_opus_attr = {
- .maxplayrate = 48000,
- .spropmaxcapturerate = 48000,
- .maxbitrate = 510000,
- .stereo = 0,
- .spropstereo = 0,
- .cbr = 0,
- .fec = 1,
- .dtx = 0,
+ .maxbitrate = CODEC_OPUS_DEFAULT_BITRATE,
+ .maxplayrate = CODEC_OPUS_DEFAULT_SAMPLE_RATE,
+ .ptime = CODEC_OPUS_DEFAULT_PTIME,
+ .stereo = CODEC_OPUS_DEFAULT_STEREO,
+ .cbr = CODEC_OPUS_DEFAULT_CBR,
+ .fec = CODEC_OPUS_DEFAULT_FEC,
+ .dtx = CODEC_OPUS_DEFAULT_DTX,
+ .spropmaxcapturerate = CODEC_OPUS_DEFAULT_SAMPLE_RATE,
+ .spropstereo = CODEC_OPUS_DEFAULT_STEREO,
+ .maxptime = CODEC_OPUS_DEFAULT_MAX_PTIME
};
static void opus_destroy(struct ast_format *format)
{
struct opus_attr *attr = ast_format_get_attribute_data(format);
+ if (!attr) {
+ return;
+ }
+
+ ao2_cleanup(attr->data);
ast_free(attr);
}
@@ -81,81 +92,65 @@ static int opus_clone(const struct ast_format *src, struct ast_format *dst)
return -1;
}
- if (original) {
- *attr = *original;
- } else {
- *attr = default_opus_attr;
- }
+ *attr = original ? *original : default_opus_attr;
+ ao2_bump(attr->data);
ast_format_set_attribute_data(dst, attr);
return 0;
}
+static void sdp_fmtp_get(const char *attributes, const char *name, int *attr)
+{
+ const char *kvp = "";
+ int val;
+
+ if (attributes && !(kvp = strstr(attributes, name))) {
+ return;
+ }
+
+ /*
+ * If the named attribute is not at the start of the given attributes, and
+ * the preceding character is not a space or semicolon then it's not the
+ * attribute we are looking for. It's an attribute with the name embedded
+ * within it (e.g. ptime in maxptime, stereo in sprop-stereo).
+ */
+ if (kvp != attributes && *(kvp - 1) != ' ' && *(kvp - 1) != ';') {
+ /* Keep searching as it might still be in the attributes string */
+ sdp_fmtp_get(strchr(kvp, ';'), name, attr);
+ /*
+ * Otherwise it's a match, so retrieve the value and set the attribute.
+ */
+ } else if (sscanf(kvp, "%*[^=]=%30d", &val) == 1) {
+ *attr = val;
+ }
+}
+
static struct ast_format *opus_parse_sdp_fmtp(const struct ast_format *format, const char *attributes)
{
struct ast_format *cloned;
struct opus_attr *attr;
- const char *kvp;
- unsigned int val;
cloned = ast_format_clone(format);
if (!cloned) {
return NULL;
}
- attr = ast_format_get_attribute_data(cloned);
-
- if ((kvp = strstr(attributes, "maxplaybackrate")) && sscanf(kvp, "maxplaybackrate=%30u", &val) == 1) {
- attr->maxplayrate = val;
- } else {
- attr->maxplayrate = 48000;
- }
-
- if ((kvp = strstr(attributes, "sprop-maxcapturerate")) && sscanf(kvp, "sprop-maxcapturerate=%30u", &val) == 1) {
- attr->spropmaxcapturerate = val;
- } else {
- attr->spropmaxcapturerate = 48000;
- }
-
- if ((kvp = strstr(attributes, "maxaveragebitrate")) && sscanf(kvp, "maxaveragebitrate=%30u", &val) == 1) {
- attr->maxbitrate = val;
- } else {
- attr->maxbitrate = 510000;
- }
- if (!strncmp(attributes, "stereo=1", 8)) {
- attr->stereo = 1;
- } else if (strstr(attributes, " stereo=1")) {
- attr->stereo = 1;
- } else if (strstr(attributes, ";stereo=1")) {
- attr->stereo = 1;
- } else {
- attr->stereo = 0;
- }
-
- if (strstr(attributes, "sprop-stereo=1")) {
- attr->spropstereo = 1;
- } else {
- attr->spropstereo = 0;
- }
+ attr = ast_format_get_attribute_data(cloned);
- if (strstr(attributes, "cbr=1")) {
- attr->cbr = 1;
- } else {
- attr->cbr = 0;
- }
-
- if (strstr(attributes, "useinbandfec=1")) {
- attr->fec = 1;
- } else {
- attr->fec = 0;
- }
-
- if (strstr(attributes, "usedtx=1")) {
- attr->dtx = 1;
- } else {
- attr->dtx = 0;
- }
+ sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_MAX_PLAYBACK_RATE, &attr->maxplayrate);
+ sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_MAX_CODED_AUDIO_BANDWIDTH,
+ &attr->maxplayrate);
+ sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_SPROP_MAX_CAPTURE_RATE,
+ &attr->spropmaxcapturerate);
+ sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_MAX_PTIME, &attr->maxptime);
+ sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_PTIME, &attr->ptime);
+ sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_MAX_AVERAGE_BITRATE, &attr->maxbitrate);
+ sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_STEREO, &attr->stereo);
+ sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_SPROP_STEREO, &attr->spropstereo);
+ sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_CBR, &attr->cbr);
+ sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_FEC, &attr->fec);
+ sdp_fmtp_get(attributes, CODEC_OPUS_ATTR_DTX, &attr->dtx);
return cloned;
}
@@ -163,7 +158,7 @@ static struct ast_format *opus_parse_sdp_fmtp(const struct ast_format *format, c
static void opus_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str)
{
struct opus_attr *attr = ast_format_get_attribute_data(format);
- int added = 0;
+ int size;
if (!attr) {
/*
@@ -174,79 +169,52 @@ static void opus_generate_sdp_fmtp(const struct ast_format *format, unsigned int
attr = &default_opus_attr;
}
- if (48000 != attr->maxplayrate) {
- if (added) {
- ast_str_append(str, 0, ";");
- } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) {
- added = 1;
- }
- ast_str_append(str, 0, "maxplaybackrate=%u", attr->maxplayrate);
+ size = ast_str_append(str, 0, "a=fmtp:%u ", payload);
+
+ if (CODEC_OPUS_DEFAULT_SAMPLE_RATE != attr->maxplayrate) {
+ ast_str_append(str, 0, "%s=%d;",
+ CODEC_OPUS_ATTR_MAX_PLAYBACK_RATE, attr->maxplayrate);
}
- if (48000 != attr->spropmaxcapturerate) {
- if (added) {
- ast_str_append(str, 0, ";");
- } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) {
- added = 1;
- }
- ast_str_append(str, 0, "sprop-maxcapturerate=%u", attr->spropmaxcapturerate);
+ if (CODEC_OPUS_DEFAULT_SAMPLE_RATE != attr->spropmaxcapturerate) {
+ ast_str_append(str, 0, "%s=%d;",
+ CODEC_OPUS_ATTR_SPROP_MAX_CAPTURE_RATE, attr->spropmaxcapturerate);
}
- if (510000 != attr->maxbitrate) {
- if (added) {
- ast_str_append(str, 0, ";");
- } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) {
- added = 1;
- }
- ast_str_append(str, 0, "maxaveragebitrate=%u", attr->maxbitrate);
+ if (CODEC_OPUS_DEFAULT_BITRATE != attr->maxbitrate || attr->maxbitrate > 0) {
+ ast_str_append(str, 0, "%s=%d;",
+ CODEC_OPUS_ATTR_MAX_AVERAGE_BITRATE, attr->maxbitrate);
}
- if (0 != attr->stereo) {
- if (added) {
- ast_str_append(str, 0, ";");
- } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) {
- added = 1;
- }
- ast_str_append(str, 0, "stereo=%u", attr->stereo);
+ if (CODEC_OPUS_DEFAULT_STEREO != attr->stereo) {
+ ast_str_append(str, 0, "%s=%d;",
+ CODEC_OPUS_ATTR_STEREO, attr->stereo);
}
- if (0 != attr->spropstereo) {
- if (added) {
- ast_str_append(str, 0, ";");
- } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) {
- added = 1;
- }
- ast_str_append(str, 0, "sprop-stereo=%u", attr->spropstereo);
+ if (CODEC_OPUS_DEFAULT_STEREO != attr->spropstereo) {
+ ast_str_append(str, 0, "%s=%d;",
+ CODEC_OPUS_ATTR_SPROP_STEREO, attr->spropstereo);
}
- if (0 != attr->cbr) {
- if (added) {
- ast_str_append(str, 0, ";");
- } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) {
- added = 1;
- }
- ast_str_append(str, 0, "cbr=%u", attr->cbr);
+ if (CODEC_OPUS_DEFAULT_CBR != attr->cbr) {
+ ast_str_append(str, 0, "%s=%d;",
+ CODEC_OPUS_ATTR_CBR, attr->cbr);
}
- if (0 != attr->fec) {
- if (added) {
- ast_str_append(str, 0, ";");
- } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) {
- added = 1;
- }
- ast_str_append(str, 0, "useinbandfec=%u", attr->fec);
+ if (CODEC_OPUS_DEFAULT_FEC!= attr->fec) {
+ ast_str_append(str, 0, "%s=%d;",
+ CODEC_OPUS_ATTR_FEC, attr->fec);
}
- if (0 != attr->dtx) {
- if (added) {
- ast_str_append(str, 0, ";");
- } else if (0 < ast_str_append(str, 0, "a=fmtp:%u ", payload)) {
- added = 1;
- }
- ast_str_append(str, 0, "usedtx=%u", attr->dtx);
+ if (CODEC_OPUS_DEFAULT_DTX != attr->dtx) {
+ ast_str_append(str, 0, "%s=%d;",
+ CODEC_OPUS_ATTR_DTX, attr->dtx);
}
- if (added) {
+ if (size == ast_str_strlen(*str)) {
+ ast_str_reset(*str);
+ } else {
+ ast_str_truncate(*str, -1);
ast_str_append(str, 0, "\r\n");
}
}
@@ -285,49 +253,68 @@ static struct ast_format *opus_getjoint(const struct ast_format *format1, const
* to receive stereo signals, it may be a waste of bandwidth. */
attr_res->stereo = attr1->stereo && attr2->stereo ? 1 : 0;
- attr_res->maxbitrate = MIN(attr1->maxbitrate, attr2->maxbitrate);
+ if (attr1->maxbitrate < 0) {
+ attr_res->maxbitrate = attr2->maxbitrate;
+ } else if (attr2->maxbitrate < 0) {
+ attr_res->maxbitrate = attr1->maxbitrate;
+ } else {
+ attr_res->maxbitrate = MIN(attr1->maxbitrate, attr2->maxbitrate);
+ }
+
attr_res->spropmaxcapturerate = MIN(attr1->spropmaxcapturerate, attr2->spropmaxcapturerate);
attr_res->maxplayrate = MIN(attr1->maxplayrate, attr2->maxplayrate);
return jointformat;
}
-static struct ast_format *opus_set(const struct ast_format *format, const char *name, const char *value)
+static struct ast_format *opus_set(const struct ast_format *format,
+ const char *name, const char *value)
{
struct ast_format *cloned;
struct opus_attr *attr;
- unsigned int val;
+ int val;
- if (sscanf(value, "%30u", &val) != 1) {
- ast_log(LOG_WARNING, "Unknown value '%s' for attribute type '%s'\n",
- value, name);
+ if (!(cloned = ast_format_clone(format))) {
return NULL;
}
- cloned = ast_format_clone(format);
- if (!cloned) {
+ attr = ast_format_get_attribute_data(cloned);
+
+ if (!strcmp(name, CODEC_OPUS_ATTR_DATA)) {
+ ao2_cleanup(attr->data);
+ attr->data = ao2_bump((void*)value);
+ return cloned;
+ }
+
+ if (sscanf(value, "%30d", &val) != 1) {
+ ast_log(LOG_WARNING, "Unknown value '%s' for attribute type '%s'\n",
+ value, name);
+ ao2_ref(cloned, -1);
return NULL;
}
- attr = ast_format_get_attribute_data(cloned);
- if (!strcasecmp(name, "max_bitrate")) {
- attr->maxbitrate = val;
- } else if (!strcasecmp(name, "max_playrate")) {
+ if (!strcasecmp(name, CODEC_OPUS_ATTR_MAX_PLAYBACK_RATE)) {
+ attr->maxplayrate = val;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_MAX_CODED_AUDIO_BANDWIDTH)) {
attr->maxplayrate = val;
- } else if (!strcasecmp(name, "minptime")) {
- attr->unused = val;
- } else if (!strcasecmp(name, "stereo")) {
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_SPROP_MAX_CAPTURE_RATE)) {
+ attr->spropmaxcapturerate = val;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_MAX_PTIME)) {
+ attr->maxptime = val;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_PTIME)) {
+ attr->ptime = val;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_MAX_AVERAGE_BITRATE)) {
+ attr->maxbitrate = val;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_STEREO)) {
attr->stereo = val;
- } else if (!strcasecmp(name, "cbr")) {
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_SPROP_STEREO)) {
+ attr->spropstereo = val;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_CBR)) {
attr->cbr = val;
- } else if (!strcasecmp(name, "fec")) {
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_FEC)) {
attr->fec = val;
- } else if (!strcasecmp(name, "dtx")) {
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_DTX)) {
attr->dtx = val;
- } else if (!strcasecmp(name, "sprop_capture_rate")) {
- attr->spropmaxcapturerate = val;
- } else if (!strcasecmp(name, "sprop_stereo")) {
- attr->spropstereo = val;
} else {
ast_log(LOG_WARNING, "unknown attribute type %s\n", name);
}
@@ -335,6 +322,44 @@ static struct ast_format *opus_set(const struct ast_format *format, const char *
return cloned;
}
+static const void *opus_get(const struct ast_format *format, const char *name)
+{
+ struct opus_attr *attr = ast_format_get_attribute_data(format);
+ int *val = NULL;
+
+ if (!attr) {
+ return NULL;
+ }
+
+ if (!strcasecmp(name, CODEC_OPUS_ATTR_DATA)) {
+ return ao2_bump(attr->data);
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_MAX_PLAYBACK_RATE)) {
+ val = &attr->maxplayrate;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_SPROP_MAX_CAPTURE_RATE)) {
+ val = &attr->spropmaxcapturerate;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_MAX_PTIME)) {
+ val = &attr->maxptime;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_PTIME)) {
+ val = &attr->ptime;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_MAX_AVERAGE_BITRATE)) {
+ val = &attr->maxbitrate;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_STEREO)) {
+ val = &attr->stereo;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_SPROP_STEREO)) {
+ val = &attr->spropstereo;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_CBR)) {
+ val = &attr->cbr;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_FEC)) {
+ val = &attr->fec;
+ } else if (!strcasecmp(name, CODEC_OPUS_ATTR_DTX)) {
+ val = &attr->dtx;
+ } else {
+ ast_log(LOG_WARNING, "unknown attribute type %s\n", name);
+ }
+
+ return val;
+}
+
static struct ast_format_interface opus_interface = {
.format_destroy = opus_destroy,
.format_clone = opus_clone,
@@ -342,11 +367,12 @@ static struct ast_format_interface opus_interface = {
.format_attribute_set = opus_set,
.format_parse_sdp_fmtp = opus_parse_sdp_fmtp,
.format_generate_sdp_fmtp = opus_generate_sdp_fmtp,
+ .format_attribute_get = opus_get
};
static int load_module(void)
{
- if (ast_format_interface_register("opus", &opus_interface)) {
+ if (__ast_format_interface_register("opus", &opus_interface, ast_module_info->self)) {
return AST_MODULE_LOAD_DECLINE;
}
@@ -358,9 +384,9 @@ static int unload_module(void)
return 0;
}
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Opus Format Attribute Module",
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Opus Format Attribute Module",
.support_level = AST_MODULE_SUPPORT_CORE,
.load = load_module,
.unload = unload_module,
- .load_pri = AST_MODPRI_CHANNEL_DEPEND,
+ .load_pri = AST_MODPRI_REALTIME_DRIVER /* Needs to load before codec_opus */
);