[svn-commits] dvossel: branch dvossel/fixtheworld_phase2 r306616 - in /team/dvossel/fixthew...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Mon Feb 7 15:42:33 CST 2011
Author: dvossel
Date: Mon Feb 7 15:42:28 2011
New Revision: 306616
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=306616
Log:
Updates to Asterisk core to allow for custom formats with translation
Modified:
team/dvossel/fixtheworld_phase2/include/asterisk/format.h
team/dvossel/fixtheworld_phase2/include/asterisk/format_cap.h
team/dvossel/fixtheworld_phase2/include/asterisk/frame.h
team/dvossel/fixtheworld_phase2/include/asterisk/rtp_engine.h
team/dvossel/fixtheworld_phase2/include/asterisk/translate.h
team/dvossel/fixtheworld_phase2/main/channel.c
team/dvossel/fixtheworld_phase2/main/format.c
team/dvossel/fixtheworld_phase2/main/format_cap.c
team/dvossel/fixtheworld_phase2/main/frame.c
team/dvossel/fixtheworld_phase2/main/rtp_engine.c
team/dvossel/fixtheworld_phase2/main/translate.c
Modified: team/dvossel/fixtheworld_phase2/include/asterisk/format.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/include/asterisk/format.h?view=diff&rev=306616&r1=306615&r2=306616
==============================================================================
--- team/dvossel/fixtheworld_phase2/include/asterisk/format.h (original)
+++ team/dvossel/fixtheworld_phase2/include/asterisk/format.h Mon Feb 7 15:42:28 2011
@@ -248,7 +248,7 @@
* \return 0, The format key value pairs are within the capabilities defined in this structure.
* \return -1, The format key value pairs are _NOT_ within the capabilities of this structure.
*/
-int ast_format_isset(struct ast_format *format, ... );
+int ast_format_isset(const struct ast_format *format, ... );
/*!
* \brief Compare ast_formats structures
Modified: team/dvossel/fixtheworld_phase2/include/asterisk/format_cap.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/include/asterisk/format_cap.h?view=diff&rev=306616&r1=306615&r2=306616
==============================================================================
--- team/dvossel/fixtheworld_phase2/include/asterisk/format_cap.h (original)
+++ team/dvossel/fixtheworld_phase2/include/asterisk/format_cap.h Mon Feb 7 15:42:28 2011
@@ -161,6 +161,14 @@
* retval 0 format is not compatible with any formats in ast_format_cap object.
*/
int ast_format_cap_iscompatible(const struct ast_format_cap *cap, const struct ast_format *format);
+
+/*!
+ * \brief Finds the best quality audio format for a given format id and returns it in result.
+ *
+ * \retval 1 format found and set to result structure.
+ * \retval 0 no format found, result structure is cleared.
+ */
+int ast_format_cap_best_byid(const struct ast_format_cap *cap, enum ast_format_id, struct ast_format *result);
/*!
* \brief is cap1 identical to cap2
Modified: team/dvossel/fixtheworld_phase2/include/asterisk/frame.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/include/asterisk/frame.h?view=diff&rev=306616&r1=306615&r2=306616
==============================================================================
--- team/dvossel/fixtheworld_phase2/include/asterisk/frame.h (original)
+++ team/dvossel/fixtheworld_phase2/include/asterisk/frame.h Mon Feb 7 15:42:28 2011
@@ -573,7 +573,7 @@
/*!
* \brief Get the sample rate for a given format.
*/
-static force_inline int ast_format_rate(struct ast_format *format)
+static force_inline int ast_format_rate(const struct ast_format *format)
{
switch (format->id) {
case AST_FORMAT_G722:
Modified: team/dvossel/fixtheworld_phase2/include/asterisk/rtp_engine.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/include/asterisk/rtp_engine.h?view=diff&rev=306616&r1=306615&r2=306616
==============================================================================
--- team/dvossel/fixtheworld_phase2/include/asterisk/rtp_engine.h (original)
+++ team/dvossel/fixtheworld_phase2/include/asterisk/rtp_engine.h Mon Feb 7 15:42:28 2011
@@ -1798,15 +1798,14 @@
int ast_rtp_instance_add_srtp_policy(struct ast_rtp_instance *instance, struct ast_srtp_policy *policy);
struct ast_srtp *ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance);
-/*! \brief Some formats can not have their mime type and payload number initialized
- * until their format attribute interface is loaded. This function is called with
- * an ast_format_id as input once one of these formats requiring attributes is loaded.*/
-int ast_rtp_engine_load_format(enum ast_format_id id);
+/*! \brief Custom formats declared in codecs.conf at startup must be communicated to the rtp_engine
+ * so their mime type can payload number can be initialized. */
+int ast_rtp_engine_load_format(const struct ast_format *format);
/*! \brief Formats requiring the use of a format attribute interface must have that
* interface registered in order for the rtp engine to handle it correctly. If an
* attribute interface is unloaded, this function must be called to notify the rtp_engine. */
-int ast_rtp_engine_unload_format(enum ast_format_id id);
+int ast_rtp_engine_unload_format(const struct ast_format *format);
/*! \brief initializes the rtp engine arrays */
int ast_rtp_engine_init(void);
Modified: team/dvossel/fixtheworld_phase2/include/asterisk/translate.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/include/asterisk/translate.h?view=diff&rev=306616&r1=306615&r2=306616
==============================================================================
--- team/dvossel/fixtheworld_phase2/include/asterisk/translate.h (original)
+++ team/dvossel/fixtheworld_phase2/include/asterisk/translate.h Mon Feb 7 15:42:28 2011
@@ -204,6 +204,12 @@
struct ast_trans_pvt {
struct ast_translator *t;
struct ast_frame f; /*!< used in frameout */
+ /*! If a translation path using a format with attributes requires the output
+ * to be a specific set of attributes, this variable will be set describing those
+ * attributes to the translator. Otherwise, the translator must choose a set
+ * of format attributes that preserves the quality of the audio in the best way
+ * possible. */
+ struct ast_format explicit_dst;
int samples; /*!< samples available in outbuf */
/*! \brief actual space used in outbuf */
int datalen;
@@ -213,7 +219,7 @@
unsigned char *uc; /*!< the useful portion of the buffer */
int16_t *i16;
uint8_t *ui8;
- } outbuf;
+ } outbuf;
plc_state_t *plc; /*!< optional plc pointer */
struct ast_trans_pvt *next; /*!< next in translator chain */
struct timeval nextin;
Modified: team/dvossel/fixtheworld_phase2/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/main/channel.c?view=diff&rev=306616&r1=306615&r2=306616
==============================================================================
--- team/dvossel/fixtheworld_phase2/main/channel.c (original)
+++ team/dvossel/fixtheworld_phase2/main/channel.c Mon Feb 7 15:42:28 2011
@@ -1037,7 +1037,7 @@
/* Find the first preferred codec in the format given */
for (x = 0; x < ARRAY_LEN(prefs); x++) {
- if (ast_format_cap_iscompatible(cap, ast_format_set(result, prefs[x], 0))) {
+ if (ast_format_cap_best_byid(cap, prefs[x], result)) {
return result;
}
}
Modified: team/dvossel/fixtheworld_phase2/main/format.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/main/format.c?view=diff&rev=306616&r1=306615&r2=306616
==============================================================================
--- team/dvossel/fixtheworld_phase2/main/format.c (original)
+++ team/dvossel/fixtheworld_phase2/main/format.c Mon Feb 7 15:42:28 2011
@@ -203,7 +203,7 @@
/*! \internal
* \brief determine if a list of attribute key value pairs are set on a format
*/
-static int format_isset_helper(struct ast_format *format, va_list ap)
+static int format_isset_helper(const struct ast_format *format, va_list ap)
{
int res;
struct interface_ao2_wrapper *wrapper;
@@ -237,7 +237,7 @@
return (res == AST_FORMAT_CMP_NOT_EQUAL) ? -1 : 0;
}
-int ast_format_isset(struct ast_format *format, ... )
+int ast_format_isset(const struct ast_format *format, ... )
{
va_list ap;
int res;
@@ -1074,6 +1074,9 @@
int ast_format_attr_reg_interface(const struct ast_format_attr_interface *interface)
{
+ int x;
+ size_t f_len;
+ const struct ast_format_list *f_list;
struct interface_ao2_wrapper *wrapper;
struct interface_ao2_wrapper tmp_wrapper = {
.id = interface->id,
@@ -1104,14 +1107,26 @@
ao2_ref(wrapper, -1);
- ast_rtp_engine_load_format(interface->id);
+ /* This will find all custom formats in codecs.conf for this new registered interface */
load_format_config();
+ /* update the RTP engine to all custom formats created for this interface */
+ f_list = ast_format_list_get(&f_len);
+ for (x = 0; x < f_len; x++) {
+ if (f_list[x].format.id == tmp_wrapper.id) {
+ ast_rtp_engine_load_format(&f_list[x].format);
+ break;
+ }
+ }
+
return 0;
}
int ast_format_attr_unreg_interface(const struct ast_format_attr_interface *interface)
{
+ int x;
+ size_t f_len;
+ const struct ast_format_list *f_list;
struct interface_ao2_wrapper *wrapper;
struct interface_ao2_wrapper tmp_wrapper = {
.id = interface->id,
@@ -1131,7 +1146,17 @@
ao2_ref(wrapper, -1);
- ast_rtp_engine_unload_format(interface->id);
+ /* update the RTP engine to remove all custom formats created for this interface */
+ f_list = ast_format_list_get(&f_len);
+ for (x = 0; x < f_len; x++) {
+ if (f_list[x].format.id == tmp_wrapper.id) {
+ ast_rtp_engine_unload_format(&f_list[x].format);
+ break;
+ }
+ }
+
+ /* This will remove all custom formats previously created for this interface */
load_format_config();
- return 0;
-}
+
+ return 0;
+}
Modified: team/dvossel/fixtheworld_phase2/main/format_cap.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/main/format_cap.c?view=diff&rev=306616&r1=306615&r2=306616
==============================================================================
--- team/dvossel/fixtheworld_phase2/main/format_cap.c (original)
+++ team/dvossel/fixtheworld_phase2/main/format_cap.c Mon Feb 7 15:42:28 2011
@@ -302,6 +302,38 @@
return 0;
}
+struct byid_data {
+ struct ast_format *result;
+ enum ast_format_id id;
+};
+static int find_best_byid_cb(void *obj, void *arg, int flag)
+{
+ struct ast_format *format = obj;
+ struct byid_data *data = arg;
+
+ if (data->id != format->id) {
+ return 0;
+ }
+ if (!data->result->id || (ast_format_rate(data->result) < ast_format_rate(format))) {
+ ast_format_copy(data->result, format);
+ }
+ return 0;
+}
+
+int ast_format_cap_best_byid(const struct ast_format_cap *cap, enum ast_format_id id, struct ast_format *result)
+{
+ struct byid_data data;
+ data.result = result;
+ data.id = id;
+
+ ast_format_clear(result);
+ ao2_callback(cap->formats,
+ OBJ_MULTIPLE | OBJ_NODATA | cap->nolock,
+ find_best_byid_cb,
+ &data);
+ return result->id ? 1 : 0;
+}
+
/*! \internal
* \brief this struct is just used for the ast_format_cap_joint function so we can provide
* both a format and a result ast_format_cap structure as arguments to the find_joint_cb
Modified: team/dvossel/fixtheworld_phase2/main/frame.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/main/frame.c?view=diff&rev=306616&r1=306615&r2=306616
==============================================================================
--- team/dvossel/fixtheworld_phase2/main/frame.c (original)
+++ team/dvossel/fixtheworld_phase2/main/frame.c Mon Feb 7 15:42:28 2011
@@ -989,6 +989,25 @@
/* 48,000 samples per second at 64kbps is 8,000 bytes per second */
samples = (int) f->datalen * ((float) 48000 / 8000);
break;
+ case AST_FORMAT_SILK:
+ if (!(ast_format_isset(&f->subclass.format,
+ SILK_ATTR_KEY_SAMP_RATE,
+ SILK_ATTR_VAL_SAMP_24KHZ,
+ AST_FORMAT_ATTR_END))) {
+ return 480;
+ } else if (!(ast_format_isset(&f->subclass.format,
+ SILK_ATTR_KEY_SAMP_RATE,
+ SILK_ATTR_VAL_SAMP_16KHZ,
+ AST_FORMAT_ATTR_END))) {
+ return 320;
+ } else if (!(ast_format_isset(&f->subclass.format,
+ SILK_ATTR_KEY_SAMP_RATE,
+ SILK_ATTR_VAL_SAMP_12KHZ,
+ AST_FORMAT_ATTR_END))) {
+ return 240;
+ } else {
+ return 160;
+ }
default:
ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(&f->subclass.format));
}
Modified: team/dvossel/fixtheworld_phase2/main/rtp_engine.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/main/rtp_engine.c?view=diff&rev=306616&r1=306615&r2=306616
==============================================================================
--- team/dvossel/fixtheworld_phase2/main/rtp_engine.c (original)
+++ team/dvossel/fixtheworld_phase2/main/rtp_engine.c Mon Feb 7 15:42:28 2011
@@ -1832,7 +1832,7 @@
return instance->srtp;
}
-static void set_next_mime_type(struct ast_format *format, int rtp_code, char *type, char *subtype, unsigned int sample_rate)
+static void set_next_mime_type(const struct ast_format *format, int rtp_code, char *type, char *subtype, unsigned int sample_rate)
{
int x = mime_types_len;
if (ARRAY_LEN(ast_rtp_mime_types) == mime_types_len) {
@@ -1853,7 +1853,7 @@
ast_rwlock_unlock(&mime_types_lock);
}
-static void add_static_payload(int map, struct ast_format *format, int rtp_code)
+static void add_static_payload(int map, const struct ast_format *format, int rtp_code)
{
int x;
ast_rwlock_wrlock(&static_RTP_PT_lock);
@@ -1882,34 +1882,12 @@
ast_rwlock_unlock(&static_RTP_PT_lock);
}
-int ast_rtp_engine_load_format(enum ast_format_id id)
-{
- struct ast_format tmpfmt;
- switch (id) {
+int ast_rtp_engine_load_format(const struct ast_format *format)
+{
+ switch (format->id) {
case AST_FORMAT_SILK:
- ast_format_set(&tmpfmt, AST_FORMAT_SILK, 1,
- SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_8KHZ,
- AST_FORMAT_ATTR_END);
- set_next_mime_type(&tmpfmt, 0, "audio", "SILK", 8000);
- add_static_payload(-1, &tmpfmt, 0);
-
- ast_format_set(&tmpfmt, AST_FORMAT_SILK, 1,
- SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_12KHZ,
- AST_FORMAT_ATTR_END);
- set_next_mime_type(&tmpfmt, 0, "audio", "SILK", 12000);
- add_static_payload(-1, &tmpfmt, 0);
-
- ast_format_set(&tmpfmt, AST_FORMAT_SILK, 1,
- SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_16KHZ,
- AST_FORMAT_ATTR_END);
- set_next_mime_type(&tmpfmt, 0, "audio", "SILK", 16000);
- add_static_payload(-1, &tmpfmt, 0);
-
- ast_format_set(&tmpfmt, AST_FORMAT_SILK, 1,
- SILK_ATTR_KEY_SAMP_RATE, SILK_ATTR_VAL_SAMP_24KHZ,
- AST_FORMAT_ATTR_END);
- set_next_mime_type(&tmpfmt, 0, "audio", "SILK", 24000);
- add_static_payload(-1, &tmpfmt, 0);
+ set_next_mime_type(format, 0, "audio", "SILK", ast_format_rate(format));
+ add_static_payload(-1, format, 0);
break;
default:
break;
@@ -1918,7 +1896,7 @@
return 0;
}
-int ast_rtp_engine_unload_format(enum ast_format_id id)
+int ast_rtp_engine_unload_format(const struct ast_format *format)
{
int x;
int y = 0;
@@ -1926,7 +1904,7 @@
ast_rwlock_wrlock(&static_RTP_PT_lock);
/* remove everything pertaining to this format id from the lists */
for (x = 0; x < AST_RTP_MAX_PT; x++) {
- if (static_RTP_PT[x].format.id == id) {
+ if (ast_format_cmp(&static_RTP_PT[x].format, format) == AST_FORMAT_CMP_EQUAL) {
memset(&static_RTP_PT[x], 0, sizeof(struct ast_rtp_payload_type));
}
}
@@ -1936,7 +1914,7 @@
ast_rwlock_wrlock(&mime_types_lock);
/* rebuild the list skipping the items matching this id */
for (x = 0; x < mime_types_len; x++) {
- if (ast_rtp_mime_types[x].payload_type.format.id == id) {
+ if (ast_format_cmp(&ast_rtp_mime_types[x].payload_type.format, format) == AST_FORMAT_CMP_EQUAL) {
continue;
}
ast_rtp_mime_types[y] = ast_rtp_mime_types[x];
Modified: team/dvossel/fixtheworld_phase2/main/translate.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase2/main/translate.c?view=diff&rev=306616&r1=306615&r2=306616
==============================================================================
--- team/dvossel/fixtheworld_phase2/main/translate.c (original)
+++ team/dvossel/fixtheworld_phase2/main/translate.c Mon Feb 7 15:42:28 2011
@@ -273,7 +273,7 @@
* \brief Allocate the descriptor, required outbuf space,
* and possibly desc.
*/
-static void *newpvt(struct ast_translator *t)
+static void *newpvt(struct ast_translator *t, const struct ast_format *explicit_dst)
{
struct ast_trans_pvt *pvt;
int len;
@@ -287,16 +287,23 @@
if (t->buf_size)
len += AST_FRIENDLY_OFFSET + t->buf_size;
pvt = ast_calloc(1, len);
- if (!pvt)
+ if (!pvt) {
return NULL;
+ }
pvt->t = t;
ofs = (char *)(pvt + 1); /* pointer to data space */
if (t->desc_size) { /* first comes the descriptor */
pvt->pvt = ofs;
ofs += t->desc_size;
}
- if (t->buf_size) /* finally buffer and header */
+ if (t->buf_size) {/* finally buffer and header */
pvt->outbuf.c = ofs + AST_FRIENDLY_OFFSET;
+ }
+ /* if a explicit destination format is provided, set that on the pvt so the
+ * translator will process it. */
+ if (explicit_dst) {
+ ast_format_copy(&pvt->explicit_dst, explicit_dst);
+ }
/* call local init routine, if present */
if (t->newpvt && t->newpvt(pvt)) {
ast_free(pvt);
@@ -424,6 +431,7 @@
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) {
int src_id = index2format(src_index);
@@ -434,7 +442,10 @@
AST_RWLIST_UNLOCK(&translators);
return NULL;
}
- if (!(cur = newpvt(t))) {
+ if (dst_index == t->dst_fmt_index) {
+ explicit_dst = dst;
+ }
+ if (!(cur = newpvt(t, explicit_dst))) {
int src_id = index2format(src_index);
int dst_id = index2format(dst_index);
ast_log(LOG_WARNING, "Failed to build translator step from %s to %s\n",
@@ -570,7 +581,7 @@
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;
More information about the svn-commits
mailing list