summaryrefslogtreecommitdiff
path: root/main/bridge_channel.c
diff options
context:
space:
mode:
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);
+}