[asterisk-commits] dvossel: branch dvossel/hd_confbridge r311734 - in /team/dvossel/hd_confbridg...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Mar 28 10:35:24 CDT 2011


Author: dvossel
Date: Mon Mar 28 10:35:20 2011
New Revision: 311734

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=311734
Log:
Allows moh to detect when write format changes occur while generating moh

Modified:
    team/dvossel/hd_confbridge/include/asterisk/channel.h
    team/dvossel/hd_confbridge/main/channel.c
    team/dvossel/hd_confbridge/res/res_musiconhold.c

Modified: team/dvossel/hd_confbridge/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/include/asterisk/channel.h?view=diff&rev=311734&r1=311733&r2=311734
==============================================================================
--- team/dvossel/hd_confbridge/include/asterisk/channel.h (original)
+++ team/dvossel/hd_confbridge/include/asterisk/channel.h Mon Mar 28 10:35:20 2011
@@ -177,6 +177,7 @@
 */
 struct ast_generator {
 	void *(*alloc)(struct ast_channel *chan, void *params);
+	/*! Channel is locked during this function callback. */
 	void (*release)(struct ast_channel *chan, void *data);
 	/*! This function gets called with the channel unlocked, but is called in
 	 *  the context of the channel thread so we know the channel is not going
@@ -185,6 +186,9 @@
 	int (*generate)(struct ast_channel *chan, void *data, int len, int samples);
 	/*! This gets called when DTMF_END frames are read from the channel */
 	void (*digit)(struct ast_channel *chan, char digit);
+	/*! This gets called when the write format on a channel is changed while
+	 * generating. The channel is locked during this callback. */
+	void (*write_format_change)(struct ast_channel *chan, void *data);
 };
 
 /*! Party name character set enumeration values (values from Q.SIG) */

Modified: team/dvossel/hd_confbridge/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/main/channel.c?view=diff&rev=311734&r1=311733&r2=311734
==============================================================================
--- team/dvossel/hd_confbridge/main/channel.c (original)
+++ team/dvossel/hd_confbridge/main/channel.c Mon Mar 28 10:35:20 2011
@@ -3007,6 +3007,15 @@
 		ast_channel_set_fd(chan, AST_GENERATOR_FD, -1);
 		ast_clear_flag(chan, AST_FLAG_WRITE_INT);
 		ast_settimeout(chan, 0, NULL, NULL);
+	}
+	ast_channel_unlock(chan);
+}
+
+static void generator_write_format_change(struct ast_channel *chan)
+{
+	ast_channel_lock(chan);
+	if (chan->generator && chan->generator->write_format_change) {
+		chan->generator->write_format_change(chan, chan->generatordata);
 	}
 	ast_channel_unlock(chan);
 }
@@ -5031,10 +5040,9 @@
 		ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", chan->name,
 			  direction ? "write" : "read", ast_getformatname(&best_set_fmt));
 
+		ast_channel_lock(chan);
 		ast_format_copy(format, &best_set_fmt);
 		ast_format_copy(rawformat, &best_set_fmt);
-
-		ast_channel_lock(chan);
 		ast_format_cap_set(chan->nativeformats, &best_set_fmt);
 		ast_channel_unlock(chan);
 
@@ -5042,6 +5050,11 @@
 			ast_translator_free_path(*trans);
 		}
 		*trans = NULL;
+		/* If there is a generator on the channel, it needs to know about this
+		 * change if it is the write format. */
+		if (direction && chan->generatordata) {
+			generator_write_format_change(chan);
+		}
 		return 0;
 	}
 
@@ -5106,6 +5119,12 @@
 		chan->name,
 		direction ? "write" : "read",
 		ast_getformatname(&best_set_fmt));
+	
+	/* If there is a generator on the channel, it needs to know about this
+	 * change if it is the write format. */
+	if (direction && chan->generatordata) {
+		generator_write_format_change(chan);
+	}
 	return res;
 }
 

Modified: team/dvossel/hd_confbridge/res/res_musiconhold.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/res/res_musiconhold.c?view=diff&rev=311734&r1=311733&r2=311734
==============================================================================
--- team/dvossel/hd_confbridge/res/res_musiconhold.c (original)
+++ team/dvossel/hd_confbridge/res/res_musiconhold.c Mon Mar 28 10:35:20 2011
@@ -153,6 +153,7 @@
 	struct mohclass *class;
 	char name[MAX_MUSICCLASS];
 	struct ast_format origwfmt;
+	struct ast_format mohwfmt;
 	int samples;
 	int sample_queue;
 	int pos;
@@ -267,6 +268,7 @@
 		ast_verbose(VERBOSE_PREFIX_3 "Stopped music on hold on %s\n", chan->name);
 	}
 
+	ast_format_clear(&state->mohwfmt); /* make sure to clear this format before restoring the original format. */
 	if (state->origwfmt.id && ast_set_write_format(chan, &state->origwfmt)) {
 		ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%s'\n", chan->name, ast_getformatname(&state->origwfmt));
 	}
@@ -355,6 +357,25 @@
 	return f;
 }
 
+static void moh_files_write_format_change(struct ast_channel *chan, void *data)
+{
+	struct moh_files_state *state = chan->music_state;
+
+	/* In order to prevent a recursive call to this function as a result
+	 * of setting the moh write format back on the channel. Clear
+	 * the moh write format before setting the write format on the channel.*/
+	if (&state->origwfmt.id) {
+		struct ast_format tmp;
+
+		ast_format_copy(&tmp, &chan->writeformat);
+		if (state->mohwfmt.id) {
+			ast_format_clear(&state->origwfmt);
+			ast_set_write_format(chan, &state->mohwfmt);
+		}
+		ast_format_copy(&state->origwfmt, &tmp);
+	}
+}
+
 static int moh_files_generator(struct ast_channel *chan, void *data, int len, int samples)
 {
 	struct moh_files_state *state = chan->music_state;
@@ -375,11 +396,8 @@
 			ast_channel_unlock(chan);
 			state->samples += f->samples;
 			state->sample_queue -= f->samples;
-			/* It is possible that while MOH is playing that the internal write format will change on a channel.
-			 * This must be detected, stored off, and restored once MOH is released */
-			if (ast_format_cmp(&chan->writeformat, &f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
-				ast_format_copy(&state->origwfmt, &chan->writeformat);
-				ast_set_write_format(chan, &f->subclass.format);
+			if (ast_format_cmp(&f->subclass.format, &state->mohwfmt) == AST_FORMAT_CMP_NOT_EQUAL) {
+				ast_format_copy(&state->mohwfmt, &f->subclass.format);
 			}
 			res = ast_write(chan, f);
 			ast_frfree(f);
@@ -425,6 +443,8 @@
 
 	state->class = mohclass_ref(class, "Reffing music class for channel");
 	ast_format_copy(&state->origwfmt, &chan->writeformat);
+	ast_format_copy(&state->mohwfmt, &chan->writeformat);
+
 	/* For comparison on restart of MOH (see above) */
 	ast_copy_string(state->name, class->name, sizeof(state->name));
 	state->save_total = class->total_files;
@@ -468,6 +488,7 @@
 	.release  = moh_files_release,
 	.generate = moh_files_generator,
 	.digit    = moh_handle_digit,
+	.write_format_change = moh_files_write_format_change,
 };
 
 static int spawn_mp3(struct mohclass *class)




More information about the asterisk-commits mailing list