[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