[svn-commits] dvossel: branch dvossel/hd_confbridge r310136 - /team/dvossel/hd_confbridge/b...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Mar 9 08:16:32 CST 2011


Author: dvossel
Date: Wed Mar  9 08:16:26 2011
New Revision: 310136

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=310136
Log:
Reorganization of the code surrounding the softmix mixing_array

I'm trying to keep the softmix mixing thread as simple as possible.
One way I'm doing this is by breaking out functionality into separate
functions when it makes sense.

Modified:
    team/dvossel/hd_confbridge/bridges/bridge_softmix.c

Modified: team/dvossel/hd_confbridge/bridges/bridge_softmix.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/bridges/bridge_softmix.c?view=diff&rev=310136&r1=310135&r2=310136
==============================================================================
--- team/dvossel/hd_confbridge/bridges/bridge_softmix.c (original)
+++ team/dvossel/hd_confbridge/bridges/bridge_softmix.c Wed Mar  9 08:16:26 2011
@@ -237,7 +237,7 @@
 	return 0;
 }
 
-struct mixing_stats {
+struct softmix_stats {
 		/*! Each index represents a sample rate used above the internal rate. */
 		unsigned int sample_rates[8];
 		/*! Each index represents the number of channels using the same index in the sample_rates array.  */
@@ -252,7 +252,7 @@
 		unsigned int locked_rate;
 };
 
-static void gather_mixing_stats(struct mixing_stats *stats,
+static void gather_softmix_stats(struct softmix_stats *stats,
 	const struct softmix_bridge_data *bridge_data,
 	struct ast_bridge_channel *bridge_channel)
 {
@@ -289,7 +289,7 @@
  * \retval 0, no changes to internal rate 
  * \ratval 1, internal rate was changed, update all the channels on the next mixing iteration.
  */
-static unsigned int analyse_mixing_stats(struct mixing_stats *stats, struct softmix_bridge_data *bridge_data)
+static unsigned int analyse_softmix_stats(struct softmix_stats *stats, struct softmix_bridge_data *bridge_data)
 {
 	int i;
 	/* Re-adjust the internal bridge sample rate if
@@ -339,25 +339,56 @@
 	return 0;
 }
 
+struct softmix_mixing_array {
+	int max_num_entries;
+	int used_entries;
+	int16_t **buffers;
+};
+
+static int softmix_mixing_array_init(struct softmix_mixing_array *mixing_array, unsigned int starting_num_entries)
+{
+	memset(mixing_array, 0, sizeof(*mixing_array));
+	mixing_array->max_num_entries = starting_num_entries;
+	if (!(mixing_array->buffers = ast_calloc(mixing_array->max_num_entries, sizeof(int16_t *)))) {
+		ast_log(LOG_NOTICE, "Failed to allocate softmix mixing structure. \n");
+		return -1;
+	}
+	return 0;
+}
+
+static void softmix_mixing_array_destroy(struct softmix_mixing_array *mixing_array)
+{
+	ast_free(mixing_array->buffers);
+}
+
+static int softmix_mixing_array_grow(struct softmix_mixing_array *mixing_array, unsigned int num_entries)
+{
+	int16_t **tmp;
+	/* give it some room to grow since memory is cheap but allocations can be expensive */
+	mixing_array->max_num_entries = num_entries;
+	if (!(tmp = ast_realloc(mixing_array->buffers, (mixing_array->max_num_entries * sizeof(int16_t *))))) {
+		ast_log(LOG_NOTICE, "Failed to re-allocate softmix mixing structure. \n");
+		return -1;
+	}
+	mixing_array->buffers = tmp;
+	return 0;
+}
+
 /*! \brief Function which acts as the mixing thread */
 static int softmix_bridge_thread(struct ast_bridge *bridge)
 {
-	struct mixing_stats stats;
+	struct softmix_stats stats;
+	struct softmix_mixing_array mixing_array;
 	struct softmix_bridge_data *bridge_data = bridge->bridge_pvt;
 	struct ast_timer *timer = bridge_data->timer;
+	int16_t buf[MAX_DATALEN] = {0, };
+	unsigned int stat_iteration_counter = 0; /* counts down, gather stats at zero and reset. */
 	int timingfd = ast_timer_fd(timer);
 	int update_all_rates = 0; /* set this when the internal sample rate has changed */
-	unsigned int stat_iteration_counter = SOFTMIX_STAT_INTERVAL; /* counts down, gather stats at zero and reset. */
 	int i, x;
-	struct {
-		int max_num_entries;
-		int used_entries;
-		int16_t **buffers;
-	} mixing_array = {
-		.max_num_entries = bridge->num + 10, /* give it room to grow, memory is cheap but allocations are expensive */
-	};
-
-	if (!(mixing_array.buffers = ast_calloc(mixing_array.max_num_entries, sizeof(int16_t *)))) {
+
+	/* give it room to grow, memory is cheap but allocations are expensive */
+	if (softmix_mixing_array_init(&mixing_array, bridge->num + 10)) {
 		ast_log(LOG_NOTICE, "Failed to allocate softmix mixing structure. \n");
 		return -1;
 	}
@@ -366,48 +397,48 @@
 
 	while (!bridge->stop && !bridge->refresh && bridge->array_num) {
 		struct ast_bridge_channel *bridge_channel = NULL;
-		int16_t buf[MAX_DATALEN] = {0, };
 		int timeout = -1;
 		unsigned int softmix_samples = SOFTMIX_SAMPLES(bridge_data->internal_rate);
 		unsigned int softmix_datalen = SOFTMIX_DATALEN(bridge_data->internal_rate);
 
+		if (softmix_datalen > MAX_DATALEN) {
+			/* This should NEVER happen, but if it does we need to know about it. */
+			ast_log(LOG_WARNING, "Conference mixing error, requested mixing length greater than mixing buffer.\n");
+			softmix_mixing_array_destroy(&mixing_array);
+			return -1;
+		}
 		/* If the number of participants in the bridge has changed, the mixing array
 		 * buffer must realloc */
-		if (mixing_array.max_num_entries < bridge->num) {
-			int16_t **tmp;
-			/* give it some room to grow since memory is cheap but allocations can be expensive */
-			mixing_array.max_num_entries = bridge->num + 5;
-			if (!(tmp = ast_realloc(mixing_array.buffers, (mixing_array.max_num_entries * sizeof(int16_t *))))) {
-				ast_log(LOG_NOTICE, "Failed to re-allocate softmix mixing structure. \n");
-				ast_free(mixing_array.buffers);
-				return -1;
-			}
-			mixing_array.buffers = tmp;
+		if (mixing_array.max_num_entries < bridge->num && softmix_mixing_array_grow(&mixing_array, bridge->num + 5)) {
+			softmix_mixing_array_destroy(&mixing_array);
+			return -1;
 		}
 		mixing_array.used_entries = 0;
 
 		/* these variables help determine if a rate change is required */
 		if (!stat_iteration_counter) {
 			memset(&stats, 0, sizeof(stats));
-		}
-		/* If the bridge has an internal sample rate set, we must lock in on that rate */
-		stats.locked_rate = bridge->internal_sample_rate;
+			/* If the bridge has an internal sample rate set, we must lock in on that rate */
+			stats.locked_rate = bridge->internal_sample_rate;
+		}
 
 		/* Go through pulling audio from each factory that has it available */
 		AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
 			struct softmix_channel *sc = bridge_channel->bridge_pvt;
 
-			if (bridge_channel->suspended) {
-				continue;
-			}
-
 			/* Update the sample rate to match the bridge's native sample rate if necessary. */
 			if (update_all_rates) {
 				set_softmix_bridge_data(bridge_data->internal_rate, bridge_channel, 1);
 			}
 
 			if (!stat_iteration_counter) {
-				gather_mixing_stats(&stats, bridge_data, bridge_channel);
+				gather_softmix_stats(&stats, bridge_data, bridge_channel);
+			}
+
+			/* if the channel is suspended, don't check for audio, but
+			 * do continue to collect statistics */
+			if (bridge_channel->suspended) {
+				continue;
 			}
 
 			ast_mutex_lock(&sc->lock);
@@ -424,6 +455,7 @@
 		}
 
 		/* mix it like crazy */
+		memset(buf, 0, softmix_datalen);
 		for (i = 0; i < mixing_array.used_entries; i++) {
 			for (x = 0; x < softmix_datalen; x++) {
 				ast_slinear_saturated_add(buf + x, mixing_array.buffers[i] + x);
@@ -456,7 +488,7 @@
 		}
 
 		if (!stat_iteration_counter) {
-			update_all_rates = analyse_mixing_stats(&stats, bridge_data);
+			update_all_rates = analyse_softmix_stats(&stats, bridge_data);
 			stat_iteration_counter = SOFTMIX_STAT_INTERVAL;
 		}
 		stat_iteration_counter--;
@@ -471,7 +503,7 @@
 		ao2_lock(bridge);
 	}
 
-	ast_free(mixing_array.buffers);
+	softmix_mixing_array_destroy(&mixing_array);
 	return 0;
 }
 




More information about the svn-commits mailing list