summaryrefslogtreecommitdiff
path: root/main/bridge_channel.c
diff options
context:
space:
mode:
authorKevin Harwell <kharwell@digium.com>2017-04-25 11:49:16 -0500
committerKevin Harwell <kharwell@digium.com>2017-05-03 16:36:22 -0500
commit7b0e3b92fd49e5fbe406ef74336e164eb3f31b6e (patch)
treebe14294023edfbb6698f4c8e8b25d529756e5aee /main/bridge_channel.c
parentbdec0852b96a9475a013f88949ad162511fd8404 (diff)
bridge_simple: Added support for streams
This patch is the first cut at adding stream support to the bridging framework. Changes were made to the framework that allows mapping of stream topologies to a bridge's supported media types. The first channel to enter a bridge initially defines the media types for a bridge (i.e. a one to one mapping is created between the bridge and the first channel). Subsequently added channels merge their media types into the bridge's adding to it when necessary. This allows channels with different sized topologies to map correctly to each other according to media type. The bridge drops any frame that does not have a matching index into a given write stream. For now though, bridge_simple will align its two channels according to size or first to join. Once both channels join the bridge the one with the most streams will indicate to the other channel to update its streams to be the same as that of the other. If both channels have the same number of streams then the first channel to join is chosen as the stream base. A topology change source was also added to a channel when a stream toplogy change request is made. This allows subsystems to know whether or not they initiated a change request. Thus avoiding potential recursive situations. ASTERISK-26966 #close Change-Id: I1eb5987921dd80c3cdcf52accc136393ca2d4163
Diffstat (limited to 'main/bridge_channel.c')
-rw-r--r--main/bridge_channel.c59
1 files changed, 58 insertions, 1 deletions
diff --git a/main/bridge_channel.c b/main/bridge_channel.c
index 89222d365..4f166fff0 100644
--- a/main/bridge_channel.c
+++ b/main/bridge_channel.c
@@ -55,6 +55,7 @@
#include "asterisk/causes.h"
#include "asterisk/test.h"
#include "asterisk/sem.h"
+#include "asterisk/stream.h"
/*!
* \brief Used to queue an action frame onto a bridge channel and write an action frame into a bridge.
@@ -982,6 +983,16 @@ int ast_bridge_channel_queue_frame(struct ast_bridge_channel *bridge_channel, st
return 0;
}
+ if (ast_channel_is_multistream(bridge_channel->chan) &&
+ (fr->frametype == AST_FRAME_IMAGE || fr->frametype == AST_FRAME_TEXT ||
+ fr->frametype == AST_FRAME_VIDEO || fr->frametype == AST_FRAME_VOICE)) {
+ /* Media frames need to be mapped to an appropriate write stream */
+ dup->stream_num = AST_VECTOR_GET(
+ &bridge_channel->stream_map.to_bridge, fr->stream_num);
+ } else {
+ dup->stream_num = -1;
+ }
+
AST_LIST_INSERT_TAIL(&bridge_channel->wr_queue, dup, frame_list);
if (ast_alertpipe_write(bridge_channel->alert_pipe)) {
ast_log(LOG_ERROR, "We couldn't write alert pipe for %p(%s)... something is VERY wrong\n",
@@ -2249,6 +2260,9 @@ static void bridge_channel_handle_control(struct ast_bridge_channel *bridge_chan
/* Should never happen. */
ast_assert(0);
break;
+ case AST_CONTROL_STREAM_TOPOLOGY_CHANGED:
+ ast_indicate_data(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
+ break;
default:
ast_indicate_data(chan, fr->subclass.integer, fr->data.ptr, fr->datalen);
break;
@@ -2268,6 +2282,7 @@ static void bridge_channel_handle_write(struct ast_bridge_channel *bridge_channe
{
struct ast_frame *fr;
struct sync_payload *sync_payload;
+ int num;
ast_bridge_channel_lock(bridge_channel);
@@ -2324,9 +2339,18 @@ static void bridge_channel_handle_write(struct ast_bridge_channel *bridge_channe
case AST_FRAME_NULL:
break;
default:
+ if (fr->stream_num >= (int)AST_VECTOR_SIZE(&bridge_channel->stream_map.to_channel)) {
+ /* Nowhere to write to, so drop it */
+ break;
+ }
+
+ /* Find what stream number to write to for the channel */
+ num = fr->stream_num < 0 ? -1 :
+ AST_VECTOR_GET(&bridge_channel->stream_map.to_channel, fr->stream_num);
+
/* Write the frame to the channel. */
bridge_channel->activity = BRIDGE_CHANNEL_THREAD_SIMPLE;
- ast_write(bridge_channel->chan, fr);
+ ast_write_stream(bridge_channel->chan, num, fr);
break;
}
bridge_frame_free(fr);
@@ -2435,6 +2459,27 @@ static void bridge_handle_trip(struct ast_bridge_channel *bridge_channel)
case AST_CONTROL_ANSWER:
ast_channel_publish_dial(NULL, bridge_channel->chan, NULL, controls[frame->subclass.integer]);
break;
+ case AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE:
+ if (bridge_channel->bridge->technology->stream_topology_request_change &&
+ bridge_channel->bridge->technology->stream_topology_request_change(
+ bridge_channel->bridge, bridge_channel)) {
+ /* Topology change was denied so drop frame */
+ bridge_frame_free(frame);
+ return;
+ }
+ break;
+ case AST_CONTROL_STREAM_TOPOLOGY_CHANGED:
+ /*
+ * If a stream topology has changed then the bridge_channel's
+ * media mapping needs to be updated.
+ */
+ ast_bridge_channel_stream_map(bridge_channel);
+
+ if (bridge_channel->bridge->technology->stream_topology_changed) {
+ bridge_channel->bridge->technology->stream_topology_changed(
+ bridge_channel->bridge, bridge_channel);
+ }
+ break;
default:
break;
}
@@ -2885,6 +2930,9 @@ static void bridge_channel_destroy(void *obj)
ao2_cleanup(bridge_channel->write_format);
ao2_cleanup(bridge_channel->read_format);
+
+ AST_VECTOR_FREE(&bridge_channel->stream_map.to_bridge);
+ AST_VECTOR_FREE(&bridge_channel->stream_map.to_channel);
}
struct ast_bridge_channel *bridge_channel_internal_alloc(struct ast_bridge *bridge)
@@ -2905,5 +2953,14 @@ struct ast_bridge_channel *bridge_channel_internal_alloc(struct ast_bridge *brid
ao2_ref(bridge_channel->bridge, +1);
}
+ /* The stream_map is initialized later - see ast_bridge_channel_stream_map */
+
return bridge_channel;
}
+
+void ast_bridge_channel_stream_map(struct ast_bridge_channel *bridge_channel)
+{
+ ast_stream_topology_map(ast_channel_get_stream_topology(bridge_channel->chan),
+ &bridge_channel->bridge->media_types, &bridge_channel->stream_map.to_bridge,
+ &bridge_channel->stream_map.to_channel);
+}