[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