[asterisk-commits] file: branch file/rtp_engine r131170 - in /team/file/rtp_engine: channels/ in...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jul 15 20:12:57 CDT 2008


Author: file
Date: Tue Jul 15 20:12:56 2008
New Revision: 131170

URL: http://svn.digium.com/view/asterisk?view=rev&rev=131170
Log:
Add early bridging into the mix.

Modified:
    team/file/rtp_engine/channels/chan_sip.c
    team/file/rtp_engine/include/asterisk/rtp_engine.h
    team/file/rtp_engine/main/rtp_engine.c

Modified: team/file/rtp_engine/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/channels/chan_sip.c?view=diff&rev=131170&r1=131169&r2=131170
==============================================================================
--- team/file/rtp_engine/channels/chan_sip.c (original)
+++ team/file/rtp_engine/channels/chan_sip.c Tue Jul 15 20:12:56 2008
@@ -2195,7 +2195,7 @@
 	.send_digit_begin = sip_senddigit_begin,	/* called with chan unlocked */
 	.send_digit_end = sip_senddigit_end,
 	.bridge = ast_rtp_instance_bridge,			/* XXX chan unlocked ? */
-//	.early_bridge = ast_rtp_early_bridge,
+	.early_bridge = ast_rtp_instance_early_bridge,
 	.send_text = sip_sendtext,		/* called with chan locked */
 	.func_channel_read = acf_channel_read,
 	.queryoption = sip_queryoption,

Modified: team/file/rtp_engine/include/asterisk/rtp_engine.h
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/include/asterisk/rtp_engine.h?view=diff&rev=131170&r1=131169&r2=131170
==============================================================================
--- team/file/rtp_engine/include/asterisk/rtp_engine.h (original)
+++ team/file/rtp_engine/include/asterisk/rtp_engine.h Tue Jul 15 20:12:56 2008
@@ -945,6 +945,18 @@
  */
 enum ast_bridge_result ast_rtp_instance_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
 
+/*! \brief Early bridge two channels that use RTP instances
+ *
+ * \param c0 First channel part of the bridge
+ * \param c1 Second channel part of the bridge
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ *
+ * \note This should only be used by channel drivers in their technology declaration.
+ */
+int ast_rtp_instance_early_bridge(struct ast_channel *c0, struct ast_channel *c1);
+
 /*! \brief Initialize RED support on an RTP instance
  *
  * \param instance The instance to initialize RED support on

Modified: team/file/rtp_engine/main/rtp_engine.c
URL: http://svn.digium.com/view/asterisk/team/file/rtp_engine/main/rtp_engine.c?view=diff&rev=131170&r1=131169&r2=131170
==============================================================================
--- team/file/rtp_engine/main/rtp_engine.c (original)
+++ team/file/rtp_engine/main/rtp_engine.c Tue Jul 15 20:12:56 2008
@@ -1142,6 +1142,80 @@
 	return res;
 }
 
+int ast_rtp_instance_early_bridge(struct ast_channel *c0, struct ast_channel *c1)
+{
+        struct ast_rtp_instance *instance0, *instance1, *vinstance0, *vinstance1, *tinstance0, *tinstance1;
+        struct ast_rtp_glue *glue0, *glue1;
+        enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID, text_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
+        enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID, text_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
+        int codec0 = 0, codec1 = 0;
+
+	/* If there is no second channel just immediately bail out, we are of no use in that scenario */
+	if (!c1) {
+		return -1;
+	}
+
+        /* Lock both channels so we can look for the glue that binds them together */
+        ast_channel_lock(c0);
+        while (ast_channel_trylock(c1)) {
+                ast_channel_unlock(c0);
+                usleep(1);
+                ast_channel_lock(c0);
+        }
+
+        /* Grab glue that binds each channel to something using the RTP engine */
+        if (!(glue0 = ast_rtp_instance_get_glue(c0->tech->type)) || !(glue1 = ast_rtp_instance_get_glue(c1->tech->type))) {
+                ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", glue0 ? c1->name : c0->name);
+                ast_channel_unlock(c0);
+                ast_channel_unlock(c1);
+                return AST_BRIDGE_FAILED;
+        }
+
+        audio_glue0_res = glue0->get_rtp_info(c0, &instance0);
+        video_glue0_res = glue0->get_vrtp_info ? glue0->get_vrtp_info(c0, &vinstance0) : AST_RTP_GLUE_RESULT_FORBID;
+        text_glue0_res = glue0->get_trtp_info ? glue0->get_trtp_info(c0, &tinstance0) : AST_RTP_GLUE_RESULT_FORBID;
+
+        audio_glue1_res = glue1->get_rtp_info(c1, &instance1);
+        video_glue1_res = glue1->get_vrtp_info ? glue1->get_vrtp_info(c1, &vinstance1) : AST_RTP_GLUE_RESULT_FORBID;
+        text_glue1_res = glue1->get_trtp_info ? glue1->get_trtp_info(c1, &tinstance1) : AST_RTP_GLUE_RESULT_FORBID;
+
+        /* If we are carrying video, and both sides are not going to remotely bridge... fail the native bridge */
+        if (video_glue0_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue0_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue0_res != AST_RTP_GLUE_RESULT_REMOTE)) {
+                audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
+        }
+        if (video_glue1_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue1_res != AST_RTP_GLUE_RESULT_REMOTE)) {
+                audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
+        }
+
+        /* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
+        if (audio_glue0_res != AST_RTP_GLUE_RESULT_REMOTE || audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE) {
+                ast_channel_unlock(c0);
+                ast_channel_unlock(c1);
+		return -1;
+        }
+
+	/* Make sure we have matching codecs */
+	codec0 = glue0->get_codec(c0);
+	codec1 = glue1->get_codec(c1);
+	if (!(codec0 & codec1)) {
+		ast_channel_unlock(c0);
+		ast_channel_unlock(c1);
+		return -1;
+	}
+
+	/* Bridge media early */
+	if (glue0->update_peer(c0, instance1, vinstance1, tinstance1, codec1, 0)) {
+		ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", c0->name, c1 ? c1->name : "<unspecified>");
+	}
+
+	ast_channel_unlock(c0);
+	ast_channel_unlock(c1);
+
+	ast_debug(1, "Setting early bridge SDP of '%s' with that of '%s'\n", c0->name, c1 ? c1->name : "<unspecified>");
+
+	return 0;
+}
+
 int ast_rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int *payloads, int generations)
 {
 	return instance->engine->red_init ? instance->engine->red_init(instance, buffer_time, payloads, generations) : -1;




More information about the asterisk-commits mailing list