[asterisk-commits] irroot: branch irroot/distrotech-customers-trunk r325997 - in /team/irroot/di...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jul 1 04:28:05 CDT 2011


Author: irroot
Date: Fri Jul  1 04:28:00 2011
New Revision: 325997

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=325997
Log:
merged changes from trunk and re-enabled automerge

Modified:
    team/irroot/distrotech-customers-trunk/   (props changed)
    team/irroot/distrotech-customers-trunk/CHANGES
    team/irroot/distrotech-customers-trunk/apps/app_confbridge.c
    team/irroot/distrotech-customers-trunk/apps/confbridge/conf_config_parser.c
    team/irroot/distrotech-customers-trunk/apps/confbridge/include/confbridge.h
    team/irroot/distrotech-customers-trunk/bridges/bridge_softmix.c
    team/irroot/distrotech-customers-trunk/cel/cel_odbc.c   (props changed)
    team/irroot/distrotech-customers-trunk/channels/chan_bridge.c
    team/irroot/distrotech-customers-trunk/channels/chan_sip.c
    team/irroot/distrotech-customers-trunk/configs/cel_odbc.conf.sample   (props changed)
    team/irroot/distrotech-customers-trunk/configs/confbridge.conf.sample
    team/irroot/distrotech-customers-trunk/configs/sip.conf.sample
    team/irroot/distrotech-customers-trunk/include/asterisk/bridging.h
    team/irroot/distrotech-customers-trunk/include/asterisk/dsp.h
    team/irroot/distrotech-customers-trunk/include/asterisk/res_fax.h
    team/irroot/distrotech-customers-trunk/main/bridging.c
    team/irroot/distrotech-customers-trunk/main/dsp.c
    team/irroot/distrotech-customers-trunk/res/res_fax.c
    team/irroot/distrotech-customers-trunk/res/res_fax_spandsp.c
    team/irroot/distrotech-customers-trunk/res/res_musiconhold.c
    team/irroot/distrotech-customers-trunk/sounds/Makefile   (props changed)

Propchange: team/irroot/distrotech-customers-trunk/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/irroot/distrotech-customers-trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.

Propchange: team/irroot/distrotech-customers-trunk/
            ('svnmerge-integrated' removed)

Modified: team/irroot/distrotech-customers-trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/CHANGES?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/CHANGES (original)
+++ team/irroot/distrotech-customers-trunk/CHANGES Fri Jul  1 04:28:00 2011
@@ -82,6 +82,8 @@
  * CONFBRIDGE_INFO dialplan function capable of retreiving information 
    about a conference such as locked status and number of parties, admins,
    and marked users.
+ * Addition of video_mode option in confbridge.conf for adding video support
+   into a bridge profile.
 
 Dialplan Variables
 ------------------
@@ -149,6 +151,16 @@
  * An autoservice is now started by default for pbx_lua channels.  It can be
    stopped and restarted using the autoservice_stop() and autoservice_start()
    functions.
+
+res_fax
+--------------------------
+ * The ReceiveFAXStatus and SendFAXStatus manager events have been consolidated
+   into a FAXStatus event with an 'Operation' header that will be either
+   'send', 'receive', and 'gateway'.
+ * T.38 gateway functionality has been added to res_fax (and res_fax_spandsp).
+   Set FAXOPT(gateway)=yes to enable this functionality on a channel. This
+   feature will handle converting a fax call between an audio T.30 fax terminal
+   and an IFP T.38 fax terminal.
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 1.6.2 to Asterisk 1.8 ----------------
@@ -671,9 +683,6 @@
    applications will be lost, and that if the 'fax' logger level is directed to
    the console, the 'core set verbose' and 'core set debug' CLI commands will
    have no effect on whether the messages appear on the console or not.
- * FAXOPT(faxgateway) will enable a framehook that will take care of T.38
-   negotiation on reciving a CED tone on a channel. this gateway is to allow
-   translation of Audio T.30 [alaw/ulaw] to IFP T.38 terminals.
 
 Miscellaneous
 -------------

Modified: team/irroot/distrotech-customers-trunk/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/apps/app_confbridge.c?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/apps/app_confbridge.c (original)
+++ team/irroot/distrotech-customers-trunk/apps/app_confbridge.c Fri Jul  1 04:28:00 2011
@@ -77,6 +77,11 @@
             <description>
                     <para>Enters the user into a specified conference bridge. The user can exit the conference by hangup or DTMF menu option.</para>
             </description>
+			<see-also>
+				<ref type="application">ConfBridge</ref>
+				<ref type="function">CONFBRIDGE</ref>
+				<ref type="function">CONFBRIDGE_INFO</ref>
+			</see-also>
     </application>
 	<function name="CONFBRIDGE" language="en_US">
 		<synopsis>
@@ -233,6 +238,19 @@
 		<description>
 		</description>
 	</manager>
+	<manager name="ConfbridgeSetSingleVideoSrc" language="en_US">
+		<synopsis>
+			Set a conference user as the single video source distributed to all other participants.
+		</synopsis>
+		<syntax>
+			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+			<parameter name="Conference" required="true" />
+			<parameter name="Channel" required="true" />
+		</syntax>
+		<description>
+		</description>
+	</manager>
+
 ***/
 
 /*!
@@ -614,6 +632,68 @@
 	return res;
 }
 
+static void handle_video_on_join(struct conference_bridge *conference_bridge, struct conference_bridge_user *conference_bridge_user)
+{
+	/* only automatically set video source for marked users */
+	if (!ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_MARKEDUSER)) {
+		return;
+	}
+
+	if (ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED)) {
+		int set = 1;
+		struct conference_bridge_user *tmp_user = NULL;
+		ao2_lock(conference_bridge);
+		/* see if anyone is already the video src */
+		AST_LIST_TRAVERSE(&conference_bridge->users_list, tmp_user, list) {
+			if (tmp_user == conference_bridge_user) {
+				continue;
+			}
+			if (ast_bridge_is_video_src(conference_bridge->bridge, tmp_user->chan)) {
+				set = 0;
+				break;
+			}
+		}
+		ao2_unlock(conference_bridge);
+		if (set) {
+			ast_bridge_set_single_src_video_mode(conference_bridge->bridge, conference_bridge_user->chan);
+		}
+	} else if (ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED)) {
+		/* we joined and are video capable, we override anyone else that may have already been the video feed */
+		ast_bridge_set_single_src_video_mode(conference_bridge->bridge, conference_bridge_user->chan);
+	}
+}
+
+static void handle_video_on_exit(struct conference_bridge *conference_bridge, struct conference_bridge_user *conference_bridge_user)
+{
+	struct conference_bridge_user *tmp_user = NULL;
+
+	/* if this isn't a video source, nothing to update */
+	if (!ast_bridge_is_video_src(conference_bridge->bridge, conference_bridge_user->chan)) {
+		return;
+	}
+
+	ast_bridge_remove_video_src(conference_bridge->bridge, conference_bridge_user->chan);
+
+	/* if the video_mode isn't set to automatically pick the video source, do nothing on exit. */
+	if (!ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED) &&
+		!ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED)) {
+		return;
+	}
+
+	/* Make the next avaliable marked user the video src.  */
+	ao2_lock(conference_bridge);
+	AST_LIST_TRAVERSE(&conference_bridge->users_list, tmp_user, list) {
+		if (tmp_user == conference_bridge_user) {
+			continue;
+		}
+		if (ast_test_flag(&tmp_user->u_profile, USER_OPT_MARKEDUSER)) {
+			ast_bridge_set_single_src_video_mode(conference_bridge->bridge, tmp_user->chan);
+			break;
+		}
+	}
+	ao2_unlock(conference_bridge);
+}
+
 /*!
  * \brief Perform post-joining marked specific actions
  *
@@ -627,7 +707,8 @@
 	if (ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_MARKEDUSER)) {
 		struct conference_bridge_user *other_conference_bridge_user = NULL;
 
-		/* If we are not the first marked user to join just bail out now */
+		/* If we are not the first user to join, then the users are already
+		 * in the conference so we do not need to update them. */
 		if (conference_bridge->markedusers >= 2) {
 			return 0;
 		}
@@ -664,7 +745,6 @@
 				other_conference_bridge_user->features.mute = 0;
 			}
 		}
-
 	} else {
 		/* If a marked user already exists in the conference bridge we can just bail out now */
 		if (conference_bridge->markedusers) {
@@ -858,6 +938,10 @@
 		ast_bridge_set_internal_sample_rate(conference_bridge->bridge, conference_bridge->b_profile.internal_sample_rate);
 		/* Set the internal mixing interval on the bridge from the bridge profile */
 		ast_bridge_set_mixing_interval(conference_bridge->bridge, conference_bridge->b_profile.mix_interval);
+
+		if (ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER)) {
+			ast_bridge_set_talker_src_video_mode(conference_bridge->bridge);
+		}
 
 		/* Setup lock for playback channel */
 		ast_mutex_init(&conference_bridge->playback_lock);
@@ -1370,6 +1454,8 @@
 		}
 	}
 
+	handle_video_on_join(conference_bridge, &conference_bridge_user);
+
 	/* Join our conference bridge for real */
 	send_join_event(conference_bridge_user.chan, conference_bridge->name);
 	ast_bridge_join(conference_bridge->bridge,
@@ -1378,6 +1464,9 @@
 		&conference_bridge_user.features,
 		&conference_bridge_user.tech_args);
 	send_leave_event(conference_bridge_user.chan, conference_bridge->name);
+
+
+	handle_video_on_exit(conference_bridge, &conference_bridge_user);
 
 	/* if this user has a intro, play it when leaving */
 	if (!quiet && !ast_strlen_zero(conference_bridge_user.name_rec_location)) {
@@ -1681,6 +1770,11 @@
 			break;
 		case MENU_ACTION_NOOP:
 			break;
+		case MENU_ACTION_SET_SINGLE_VIDEO_SRC:
+			ao2_lock(conference_bridge);
+			ast_bridge_set_single_src_video_mode(conference_bridge->bridge, bridge_channel->chan);
+			ao2_unlock(conference_bridge);
+			break;
 		}
 	}
 	return res;
@@ -2436,6 +2530,55 @@
 	return 0;
 }
 
+static int action_confbridgesetsinglevideosrc(struct mansession *s, const struct message *m)
+{
+	const char *conference = astman_get_header(m, "Conference");
+	const char *channel = astman_get_header(m, "Channel");
+	struct conference_bridge_user *participant = NULL;
+	struct conference_bridge *bridge = NULL;
+	struct conference_bridge tmp;
+
+	if (ast_strlen_zero(conference)) {
+		astman_send_error(s, m, "No Conference name provided.");
+		return 0;
+	}
+	if (ast_strlen_zero(channel)) {
+		astman_send_error(s, m, "No channel name provided.");
+		return 0;
+	}
+	if (!ao2_container_count(conference_bridges)) {
+		astman_send_error(s, m, "No active conferences.");
+		return 0;
+	}
+
+	ast_copy_string(tmp.name, conference, sizeof(tmp.name));
+	bridge = ao2_find(conference_bridges, &tmp, OBJ_POINTER);
+	if (!bridge) {
+		astman_send_error(s, m, "No Conference by that name found.");
+		return 0;
+	}
+
+	/* find channel and set as video src. */
+	ao2_lock(bridge);
+	AST_LIST_TRAVERSE(&bridge->users_list, participant, list) {
+		if (!strncmp(channel, participant->chan->name, strlen(channel))) {
+			ast_bridge_set_single_src_video_mode(bridge->bridge, participant->chan);
+			break;
+		}
+	}
+	ao2_unlock(bridge);
+	ao2_ref(bridge, -1);
+
+	/* do not access participant after bridge unlock.  We are just
+	 * using this check to see if it was found or not */
+	if (!participant) {
+		astman_send_error(s, m, "No channel by that name found in conference.");
+		return 0;
+	}
+	astman_send_ack(s, m, "Conference single video source set.");
+	return 0;
+}
+
 static int func_confbridge_info(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 {
 	char *parse = NULL;
@@ -2567,6 +2710,7 @@
 	res |= ast_manager_register_xml("ConfbridgeLock", EVENT_FLAG_CALL, action_confbridgelock);
 	res |= ast_manager_register_xml("ConfbridgeStartRecord", EVENT_FLAG_CALL, action_confbridgestartrecord);
 	res |= ast_manager_register_xml("ConfbridgeStopRecord", EVENT_FLAG_CALL, action_confbridgestoprecord);
+	res |= ast_manager_register_xml("ConfbridgeSetSingleVideoSrc", EVENT_FLAG_CALL, action_confbridgesetsinglevideosrc);
 
 	conf_load_config(0);
 	return res;

Modified: team/irroot/distrotech-customers-trunk/apps/confbridge/conf_config_parser.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/apps/confbridge/conf_config_parser.c?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/apps/confbridge/conf_config_parser.c (original)
+++ team/irroot/distrotech-customers-trunk/apps/confbridge/conf_config_parser.c Fri Jul  1 04:28:00 2011
@@ -284,6 +284,14 @@
 		}
 	} else if (!strcasecmp(name, "record_conference")) {
 		ast_set2_flag(b_profile, ast_true(value), BRIDGE_OPT_RECORD_CONFERENCE);
+	} else if (!strcasecmp(name, "video_mode")) {
+		if (!strcasecmp(value, "first_marked")) {
+			ast_set_flag(b_profile, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED);
+		} else if (!strcasecmp(value, "last_marked")) {
+			ast_set_flag(b_profile, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED);
+		} else if (!strcasecmp(value, "follow_talker")) {
+			ast_set_flag(b_profile, BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER);
+		}
 	} else if (!strcasecmp(name, "max_members")) {
 		if (sscanf(value, "%30u", &b_profile->max_members) != 1) {
 			return -1;
@@ -534,6 +542,7 @@
 	case MENU_ACTION_ADMIN_TOGGLE_LOCK:
 	case MENU_ACTION_ADMIN_KICK_LAST:
 	case MENU_ACTION_LEAVE:
+	case MENU_ACTION_SET_SINGLE_VIDEO_SRC:
 		break;
 	case MENU_ACTION_PLAYBACK:
 	case MENU_ACTION_PLAYBACK_AND_CONTINUE:
@@ -649,6 +658,8 @@
 			res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_ADMIN_KICK_LAST, NULL);
 		} else if (!strcasecmp(action, "leave_conference")) {
 			res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_LEAVE, NULL);
+		} else if (!strcasecmp(action, "set_as_single_video_src")) {
+			res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_SET_SINGLE_VIDEO_SRC, NULL);
 		} else if (!strncasecmp(action, "dialplan_exec(", 14)) {
 			ast_copy_string(buf, action, sizeof(buf));
 			action_args = buf;
@@ -983,6 +994,16 @@
 		ast_cli(a->fd,"Max Members:          No Limit\n");
 	}
 
+	if (b_profile.flags & BRIDGE_OPT_VIDEO_SRC_LAST_MARKED) {
+		ast_cli(a->fd, "Video Mode:           last_marked\n");
+	} else if (b_profile.flags & BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED) {
+		ast_cli(a->fd, "Video Mode:           first_marked\n");
+	} else if (b_profile.flags & BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER) {
+		ast_cli(a->fd, "Video Mode:           follow_talker\n");
+	} else {
+		ast_cli(a->fd, "Video Mode:           no video\n");
+	}
+
 	ast_cli(a->fd,"sound_join:           %s\n", conf_get_sound(CONF_SOUND_JOIN, b_profile.sounds));
 	ast_cli(a->fd,"sound_leave:          %s\n", conf_get_sound(CONF_SOUND_LEAVE, b_profile.sounds));
 	ast_cli(a->fd,"sound_only_person:    %s\n", conf_get_sound(CONF_SOUND_ONLY_PERSON, b_profile.sounds));
@@ -1142,6 +1163,9 @@
 			case MENU_ACTION_LEAVE:
 				ast_cli(a->fd, "leave_conference");
 				break;
+			case MENU_ACTION_SET_SINGLE_VIDEO_SRC:
+				ast_cli(a->fd, "set_as_single_video_src");
+				break;
 			}
 			action_num++;
 		}

Modified: team/irroot/distrotech-customers-trunk/apps/confbridge/include/confbridge.h
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/apps/confbridge/include/confbridge.h?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/apps/confbridge/include/confbridge.h (original)
+++ team/irroot/distrotech-customers-trunk/apps/confbridge/include/confbridge.h Fri Jul  1 04:28:00 2011
@@ -61,6 +61,9 @@
 
 enum bridge_profile_flags {
 	BRIDGE_OPT_RECORD_CONFERENCE = (1 << 0), /*!< Set if the conference should be recorded */
+	BRIDGE_OPT_VIDEO_SRC_LAST_MARKED = (1 << 1), /*!< Set if conference should feed video of last marked user to all participants. */
+	BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED = (1 << 2), /*!< Set if conference should feed video of first marked user to all participants. */
+	BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER = (1 << 3), /*!< Set if conference set the video feed to follow the loudest talker.  */
 };
 
 enum conf_menu_action_id {
@@ -78,6 +81,7 @@
 	MENU_ACTION_ADMIN_KICK_LAST,
 	MENU_ACTION_LEAVE,
 	MENU_ACTION_NOOP,
+	MENU_ACTION_SET_SINGLE_VIDEO_SRC,
 };
 
 /*! The conference menu action contains both

Modified: team/irroot/distrotech-customers-trunk/bridges/bridge_softmix.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/bridges/bridge_softmix.c?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/bridges/bridge_softmix.c (original)
+++ team/irroot/distrotech-customers-trunk/bridges/bridge_softmix.c Fri Jul  1 04:28:00 2011
@@ -69,6 +69,20 @@
  * mixed out its own write audio stream because it is not talking. */
 #define DEFAULT_SOFTMIX_SILENCE_THRESHOLD 2500
 #define DEFAULT_SOFTMIX_TALKING_THRESHOLD 160
+
+#define DEFAULT_ENERGY_HISTORY_LEN 150
+
+struct video_follow_talker_data {
+	/*! audio energy history */
+	int energy_history[DEFAULT_ENERGY_HISTORY_LEN];
+	/*! The current slot being used in the history buffer, this
+	 *  increments and wraps around */
+	int energy_history_cur_slot;
+	/*! The current energy sum used for averages. */
+	int energy_accum;
+	/*! The current energy average */
+	int energy_average;
+};
 
 /*! \brief Structure which contains per-channel mixing information */
 struct softmix_channel {
@@ -93,6 +107,8 @@
 	short final_buf[MAX_DATALEN];
 	/*! Buffer containing only the audio from the channel */
 	short our_buf[MAX_DATALEN];
+	/*! Data pertaining to talker mode for video conferencing */
+	struct video_follow_talker_data video_talker;
 };
 
 struct softmix_bridge_data {
@@ -419,12 +435,24 @@
 	}
 }
 
+static void softmix_pass_video(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
+{
+	struct ast_bridge_channel *tmp;
+	AST_LIST_TRAVERSE(&bridge->channels, tmp, entry) {
+		if (tmp->suspended) {
+			continue;
+		}
+		ast_write(tmp->chan, frame);
+	}
+}
+
 /*! \brief Function called when a channel writes a frame into the bridge */
 static enum ast_bridge_write_result softmix_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
 {
 	struct softmix_channel *sc = bridge_channel->bridge_pvt;
 	struct softmix_bridge_data *softmix_data = bridge->bridge_pvt;
 	int totalsilence = 0;
+	int cur_energy = 0;
 	int silence_threshold = bridge_channel->tech_args.silence_threshold ?
 		bridge_channel->tech_args.silence_threshold :
 		DEFAULT_SOFTMIX_SILENCE_THRESHOLD;
@@ -434,18 +462,52 @@
 	/* Only accept audio frames, all others are unsupported */
 	if (frame->frametype == AST_FRAME_DTMF_END || frame->frametype == AST_FRAME_DTMF_BEGIN) {
 		softmix_pass_dtmf(bridge, bridge_channel, frame);
-		goto no_audio;
-	} else if (frame->frametype != AST_FRAME_VOICE) {
+		goto bridge_write_cleanup;
+	} else if (frame->frametype != AST_FRAME_VOICE && frame->frametype != AST_FRAME_VIDEO) {
 		res = AST_BRIDGE_WRITE_UNSUPPORTED;
-		goto no_audio;
+		goto bridge_write_cleanup;
 	} else if (frame->datalen == 0) {
-		goto no_audio;
+		goto bridge_write_cleanup;
+	}
+
+	/* Determine if this video frame should be distributed or not */
+	if (frame->frametype == AST_FRAME_VIDEO) {
+		switch (bridge->video_mode.mode) {
+		case AST_BRIDGE_VIDEO_MODE_NONE:
+			break;
+		case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
+			if (ast_bridge_is_video_src(bridge, bridge_channel->chan)) {
+				softmix_pass_video(bridge, bridge_channel, frame);
+			}
+			break;
+		case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
+			ast_mutex_lock(&sc->lock);
+			ast_bridge_update_talker_src_video_mode(bridge, bridge_channel->chan, sc->video_talker.energy_average, ast_format_get_video_mark(&frame->subclass.format));
+			ast_mutex_unlock(&sc->lock);
+			if (ast_bridge_is_video_src(bridge, bridge_channel->chan)) {
+				softmix_pass_video(bridge, bridge_channel, frame);
+			}
+			break;
+		}
+		goto bridge_write_cleanup;
 	}
 
 	/* If we made it here, we are going to write the frame into the conference */
 	ast_mutex_lock(&sc->lock);
-
-	ast_dsp_silence(sc->dsp, frame, &totalsilence);
+	ast_dsp_silence_with_energy(sc->dsp, frame, &totalsilence, &cur_energy);
+
+	if (bridge->video_mode.mode == AST_BRIDGE_VIDEO_MODE_TALKER_SRC) {
+		int cur_slot = sc->video_talker.energy_history_cur_slot;
+		sc->video_talker.energy_accum -= sc->video_talker.energy_history[cur_slot];
+		sc->video_talker.energy_accum += cur_energy;
+		sc->video_talker.energy_history[cur_slot] = cur_energy;
+		sc->video_talker.energy_average = sc->video_talker.energy_accum / DEFAULT_ENERGY_HISTORY_LEN;
+		sc->video_talker.energy_history_cur_slot++;
+		if (sc->video_talker.energy_history_cur_slot == DEFAULT_ENERGY_HISTORY_LEN) {
+			sc->video_talker.energy_history_cur_slot = 0; /* wrap around */
+		}
+	}
+
 	if (totalsilence < silence_threshold) {
 		if (!sc->talking) {
 			update_talking = 1;
@@ -487,7 +549,7 @@
 
 	return res;
 
-no_audio:
+bridge_write_cleanup:
 	/* Even though the frame is not being written into the conference because it is not audio,
 	 * we should use this opportunity to check to see if a frame is ready to be written out from
 	 * the conference to the channel. */
@@ -817,7 +879,7 @@
 
 static struct ast_bridge_technology softmix_bridge = {
 	.name = "softmix",
-	.capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX | AST_BRIDGE_CAPABILITY_THREAD | AST_BRIDGE_CAPABILITY_MULTITHREADED | AST_BRIDGE_CAPABILITY_OPTIMIZE,
+	.capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX | AST_BRIDGE_CAPABILITY_THREAD | AST_BRIDGE_CAPABILITY_MULTITHREADED | AST_BRIDGE_CAPABILITY_OPTIMIZE | AST_BRIDGE_CAPABILITY_VIDEO,
 	.preference = AST_BRIDGE_PREFERENCE_LOW,
 	.create = softmix_bridge_create,
 	.destroy = softmix_bridge_destroy,

Propchange: team/irroot/distrotech-customers-trunk/cel/cel_odbc.c
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jul  1 04:28:00 2011
@@ -1,1 +1,2 @@
 /be/branches/C.3/cel/cel_adaptive_odbc.c:256426
+/trunk/cel/cel_odbc.c:319002-325996

Modified: team/irroot/distrotech-customers-trunk/channels/chan_bridge.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/channels/chan_bridge.c?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/channels/chan_bridge.c (original)
+++ team/irroot/distrotech-customers-trunk/channels/chan_bridge.c Fri Jul  1 04:28:00 2011
@@ -229,6 +229,9 @@
 	ast_format_copy(&p->input->rawwriteformat, &slin);
 	ast_format_copy(&p->output->rawwriteformat, &slin);
 
+	ast_answer(p->output);
+	ast_answer(p->input);
+
 	return p->input;
 }
 

Modified: team/irroot/distrotech-customers-trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/channels/chan_sip.c?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/channels/chan_sip.c (original)
+++ team/irroot/distrotech-customers-trunk/channels/chan_sip.c Fri Jul  1 04:28:00 2011
@@ -1335,7 +1335,6 @@
 
 /*--- Misc functions */
 static void check_rtp_timeout(struct sip_pvt *dialog, time_t t);
-static int sip_do_reload(enum channelreloadreason reason);
 static int reload_config(enum channelreloadreason reason);
 static int expire_register(const void *data);
 static void *do_monitor(void *data);
@@ -13427,7 +13426,7 @@
 	return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
 }
 
-/*! \brief return the request and response heade for a 401 or 407 code */
+/*! \brief return the request and response header for a 401 or 407 code */
 static void auth_headers(enum sip_auth_type code, char **header, char **respheader)
 {
 	if (code == WWW_AUTH) {			/* 401 */
@@ -17394,13 +17393,13 @@
 		ast_cli(fd, "  Status       : ");
 		peer_status(peer, status, sizeof(status));
 		ast_cli(fd, "%s\n", status);
- 		ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
- 		ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
+		ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
+		ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
 		ast_cli(fd, "  Qualify Freq : %d ms\n", peer->qualifyfreq);
 		if (peer->chanvars) {
- 			ast_cli(fd, "  Variables    :\n");
+			ast_cli(fd, "  Variables    :\n");
 			for (v = peer->chanvars ; v ; v = v->next)
- 				ast_cli(fd, "                 %s = %s\n", v->name, v->value);
+				ast_cli(fd, "                 %s = %s\n", v->name, v->value);
 		}
 
 		ast_cli(fd, "  Sess-Timers  : %s\n", stmode2str(peer->stimer.st_mode_oper));
@@ -17494,13 +17493,13 @@
 		astman_append(s, "Status: ");
 		peer_status(peer, status, sizeof(status));
 		astman_append(s, "%s\r\n", status);
- 		astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
- 		astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact);
+		astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
+		astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact);
 		astman_append(s, "QualifyFreq: %d ms\r\n", peer->qualifyfreq);
 		astman_append(s, "Parkinglot: %s\r\n", peer->parkinglot);
 		if (peer->chanvars) {
 			for (v = peer->chanvars ; v ; v = v->next) {
- 				astman_append(s, "ChanVariable: %s=%s\r\n", v->name, v->value);
+				astman_append(s, "ChanVariable: %s=%s\r\n", v->name, v->value);
 			}
 		}
 		astman_append(s, "SIP-Use-Reason-Header : %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_Q850_REASON)) ? "Y" : "N");
@@ -19130,7 +19129,7 @@
 		username = p->authname;
  		secret = p->relatedpeer 
 			&& !ast_strlen_zero(p->relatedpeer->remotesecret)
-			? p->relatedpeer->remotesecret : p->peersecret;
+				? p->relatedpeer->remotesecret : p->peersecret;
 		md5secret = p->peermd5secret;
 	}
 	if (ast_strlen_zero(username))	/* We have no authentication */
@@ -19154,7 +19153,7 @@
 
 	/* only include the opaque string if it's set */
 	if (!ast_strlen_zero(p->opaque)) {
-	  snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
+		snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
 	}
 
 	/* XXX We hard code our qop to "auth" for now.  XXX */
@@ -30061,6 +30060,7 @@
 	if (!(sip_tech.capabilities = ast_format_cap_alloc())) {
 		return AST_MODULE_LOAD_FAILURE;
 	}
+
 	/* the fact that ao2_containers can't resize automatically is a major worry! */
 	/* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */
 	peers = ao2_t_container_alloc(HASH_PEER_SIZE, peer_hash_cb, peer_cmp_cb, "allocate peers");
@@ -30069,6 +30069,11 @@
 	dialogs_needdestroy = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs_needdestroy");
 	dialogs_rtpcheck = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs for rtpchecks");
 	threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table");
+	if (!peers || !peers_by_ip || !dialogs || !dialogs_needdestroy || !dialogs_rtpcheck
+		|| !threadt) {
+		ast_log(LOG_ERROR, "Unable to create primary SIP container(s)\n");
+		return AST_MODULE_LOAD_FAILURE;
+	}
 
 	if (!(sip_cfg.caps = ast_format_cap_alloc())) {
 		return AST_MODULE_LOAD_FAILURE;
@@ -30092,7 +30097,7 @@
 	sip_reloadreason = CHANNEL_MODULE_LOAD;
 
 	can_parse_xml = sip_is_xml_parsable();
-	if(reload_config(sip_reloadreason)) {	/* Load the configuration from sip.conf */
+	if (reload_config(sip_reloadreason)) {	/* Load the configuration from sip.conf */
 		return AST_MODULE_LOAD_DECLINE;
 	}
 

Propchange: team/irroot/distrotech-customers-trunk/configs/cel_odbc.conf.sample
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jul  1 04:28:00 2011
@@ -1,1 +1,2 @@
 /be/branches/C.3/configs/cel_adaptive_odbc.conf.sample:256426
+/trunk/configs/cel_odbc.conf.sample:319002-325996

Modified: team/irroot/distrotech-customers-trunk/configs/confbridge.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/configs/confbridge.conf.sample?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/configs/confbridge.conf.sample (original)
+++ team/irroot/distrotech-customers-trunk/configs/confbridge.conf.sample Fri Jul  1 04:28:00 2011
@@ -167,6 +167,26 @@
                         ; be chosen.  Using a larger mixing interval comes at the cost of introducing
                         ; larger amounts of delay into the bridge.  Valid values here are 10, 20, 40,
                         ; or 80.  By default 20ms is used.
+
+;video_mode = follow_talker ; Sets how confbridge handles video distribution to the conference participants.
+                           ; Note that participants wanting to view and be the source of a video feed
+                           ; _MUST_ be sharing the same video codec.
+                           ; --- MODES ---
+                           ; none: No video sources are set by default in the conference. It is still
+                           ;       possible for a user to be set as a video source via AMI or DTMF action
+                           ;       at any time.
+                           ;
+                           ; follow_talker: The video feed will follow whoever is talking and providing video.
+                           ;
+                           ; last_marked: The last marked user to join the conference with video capabilities
+                           ;              will be the single source of video distributed to all participants.
+                           ;              If multiple marked users are capable of video, the last one to join
+                           ;              is always the source, when that user leaves it goes to the one who
+                           ;              joined before them.
+                           ;
+                           ; first_marked: The first marked user to join the conference with video capabilities
+                           ;               is the single source of video distribution among all participants. If
+                           ;               that user leaves, the marked user to join after them becomes the source.
 
 ; All sounds in the conference are customizable using the bridge profile options below.
 ; Simply state the option followed by the filename or full path of the filename after
@@ -264,6 +284,8 @@
 ; admin_toggle_conference_lock ; This action allows an Admin to toggle locking and
                                ; unlocking the conference.  Non admins can not use
                                ; this action even if it is in their menu.
+; set_as_single_video_src   ; This action allows any user to set themselves as the
+                            ; single video source distributed to all participants.
 
 [sample_user_menu]
 type=menu

Modified: team/irroot/distrotech-customers-trunk/configs/sip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/configs/sip.conf.sample?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/configs/sip.conf.sample (original)
+++ team/irroot/distrotech-customers-trunk/configs/sip.conf.sample Fri Jul  1 04:28:00 2011
@@ -130,7 +130,7 @@
                                 ; asterisk.conf, it defaults to that system name
                                 ; Realms MUST be globally unique according to RFC 3261
                                 ; Set this to your host name or domain name
-;domainsasrealm=no              ; Use domans list as realms
+;domainsasrealm=no              ; Use domains list as realms
                                 ; You can serve multiple Realms specifying several
                                 ; 'domain=...' directives (see below). 
                                 ; In this case Realm will be based on request 'From'/'To' header

Modified: team/irroot/distrotech-customers-trunk/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/include/asterisk/bridging.h?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/include/asterisk/bridging.h (original)
+++ team/irroot/distrotech-customers-trunk/include/asterisk/bridging.h Fri Jul  1 04:28:00 2011
@@ -167,12 +167,48 @@
 	AST_LIST_ENTRY(ast_bridge_channel) entry;
 };
 
+enum ast_bridge_video_mode_type {
+	/*! Video is not allowed in the bridge */
+	AST_BRIDGE_VIDEO_MODE_NONE = 0,
+	/*! A single user is picked as the only distributed of video across the bridge */
+	AST_BRIDGE_VIDEO_MODE_SINGLE_SRC,
+	/*! A single user's video feed is distributed to all bridge channels, but
+	 *  that feed is automatically picked based on who is talking the most. */
+	AST_BRIDGE_VIDEO_MODE_TALKER_SRC,
+};
+
+/*! This is used for both SINGLE_SRC mode to set what channel
+ *  should be the current single video feed */
+struct ast_bridge_video_single_src_data {
+	/*! Only accept video coming from this channel */
+	struct ast_channel *chan_vsrc;
+};
+
+/*! This is used for both SINGLE_SRC_TALKER mode to set what channel
+ *  should be the current single video feed */
+struct ast_bridge_video_talker_src_data {
+	/*! Only accept video coming from this channel */
+	struct ast_channel *chan_vsrc;
+	int average_talking_energy;
+};
+
+struct ast_bridge_video_mode {
+	enum ast_bridge_video_mode_type mode;
+	/* Add data for all the video modes here. */
+	union {
+		struct ast_bridge_video_single_src_data single_src_data;
+		struct ast_bridge_video_talker_src_data talker_src_data;
+	} mode_data;
+};
+
 /*!
  * \brief Structure that contains information about a bridge
  */
 struct ast_bridge {
 	/*! Number of channels participating in the bridge */
 	int num;
+	/*! The video mode this bridge is using */
+	struct ast_bridge_video_mode video_mode;
 	/*! The internal sample rate this bridge is mixed at when multiple channels are being mixed.
 	 *  If this value is 0, the bridge technology may auto adjust the internal mixing rate. */
 	unsigned int internal_sample_rate;
@@ -475,6 +511,31 @@
  */
 void ast_bridge_set_mixing_interval(struct ast_bridge *bridge, unsigned int mixing_interval);
 
+/*!
+ * \brief Set a bridge to feed a single video source to all participants.
+ */
+void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan);
+
+/*!
+ * \brief Set the bridge to pick the strongest talker supporting
+ * video as the single source video feed
+ */
+void ast_bridge_set_talker_src_video_mode(struct ast_bridge *bridge);
+
+/*!
+ * \brief Update information about talker energy for talker src video mode.
+ */
+void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyfame);
+
+/*!
+ * \brief Determine if a channel is a video src for the bridge
+ */
+int ast_bridge_is_video_src(struct ast_bridge *bridge, struct ast_channel *chan);
+
+/*!
+ * \brief remove a channel as a source of video for the bridge.
+ */
+void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }

Modified: team/irroot/distrotech-customers-trunk/include/asterisk/dsp.h
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/include/asterisk/dsp.h?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/include/asterisk/dsp.h (original)
+++ team/irroot/distrotech-customers-trunk/include/asterisk/dsp.h Fri Jul  1 04:28:00 2011
@@ -109,6 +109,11 @@
    number of seconds of silence  */
 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence);
 
+/*! \brief Return non-zero if this is silence.  Updates "totalsilence" with the total
+   number of seconds of silence. Returns the average energy of the samples in the frame
+   in frames_energy variable. */
+int ast_dsp_silence_with_energy(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence, int *frames_energy);
+
 /*!
  * \brief Return non-zero if this is noise.  Updates "totalnoise" with the total
  * number of seconds of noise

Modified: team/irroot/distrotech-customers-trunk/include/asterisk/res_fax.h
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/include/asterisk/res_fax.h?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/include/asterisk/res_fax.h (original)
+++ team/irroot/distrotech-customers-trunk/include/asterisk/res_fax.h Fri Jul  1 04:28:00 2011
@@ -160,8 +160,6 @@
 			uint32_t send_cng:1;
 			/*! send a T.38 reinvite */
 			uint32_t request_t38:1;
-			/*! T.38 Gateway enable */
-			uint32_t t38gateway:1;
 		};
 	} option;
 	/*! override the minimum transmission rate with a channel variable */
@@ -172,6 +170,8 @@
 	struct ast_fax_t38_parameters our_t38_parameters;
 	/*! the other endpoint's T.38 session parameters, if any */
 	struct ast_fax_t38_parameters their_t38_parameters;
+	/*! the id of the t.38 gateway framehook for this channel */
+	int gateway_id;
 };
 
 struct ast_fax_tech;
@@ -210,24 +210,6 @@
 
 /* if this overlaps with any AST_FRFLAG_* values, problems will occur */
 #define AST_FAX_FRFLAG_GATEWAY (1 << 13)
-
-/*! \brief used for gateway framehook */
-struct ast_fax_session_gateway {
-	/*! FAX Session*/
-	struct ast_fax_session *s;
-	/*! DSP Processor*/
-	struct ast_dsp *chan_dsp;
-	struct ast_dsp *peer_dsp;
-	/*! framehook used in gateway mode */
-	int framehook;
-	/*! bridged*/
-	int bridged;
-	/*Original audio formats*/
-	struct ast_format chan_read_format;
-	struct ast_format chan_write_format;
-	struct ast_format peer_read_format;
-	struct ast_format peer_write_format;
-};
 
 /*! \brief used to register a FAX technology module with res_fax */
 struct ast_fax_tech {

Modified: team/irroot/distrotech-customers-trunk/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/main/bridging.c?view=diff&rev=325997&r1=325996&r2=325997
==============================================================================
--- team/irroot/distrotech-customers-trunk/main/bridging.c (original)
+++ team/irroot/distrotech-customers-trunk/main/bridging.c Fri Jul  1 04:28:00 2011
@@ -50,6 +50,8 @@
 /* Grow rate of bridge array of channels */
 #define BRIDGE_ARRAY_GROW 32
 
+static void cleanup_video_mode(struct ast_bridge *bridge);
+
 /*! Default DTMF keys for built in features */
 static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING];
 
@@ -456,6 +458,8 @@
 
 	/* Drop the array of channels */
 	ast_free(bridge->array);
+
+	cleanup_video_mode(bridge);
 
 	return;
 }
@@ -1470,3 +1474,116 @@
 	bridge->internal_sample_rate = sample_rate;

[... 2136 lines stripped ...]



More information about the asterisk-commits mailing list