stream: Add stream topology to channel

Adds topology set and get to channel.

ASTERISK-26790

Change-Id: Ic379ea82a9486fc79dbd8c4d95c29fa3b46424f4
This commit is contained in:
George Joseph
2017-02-13 10:50:47 -07:00
parent 6c4657e28e
commit bf2f091bbb
7 changed files with 186 additions and 4 deletions

View File

@@ -46,6 +46,7 @@
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_endpoints.h"
#include "asterisk/stringfields.h"
#include "asterisk/stream.h"
#include "asterisk/test.h"
/*!
@@ -221,6 +222,8 @@ struct ast_channel {
struct stasis_cp_single *topics; /*!< Topic for all channel's events */
struct stasis_forward *endpoint_forward; /*!< Subscription for event forwarding to endpoint's topic */
struct stasis_forward *endpoint_cache_forward; /*!< Subscription for cache updates to endpoint's topic */
struct ast_stream_topology *stream_topology; /*!< Stream topology */
struct ast_stream *default_streams[AST_MEDIA_TYPE_END]; /*!< Default streams indexed by media type */
};
/*! \brief The monotonically increasing integer counter for channel uniqueids */
@@ -825,10 +828,57 @@ struct ast_format_cap *ast_channel_nativeformats(const struct ast_channel *chan)
{
return chan->nativeformats;
}
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
static void channel_set_default_streams(struct ast_channel *chan)
{
ao2_replace(chan->nativeformats, value);
enum ast_media_type type;
ast_assert(chan != NULL);
for (type = AST_MEDIA_TYPE_UNKNOWN; type < AST_MEDIA_TYPE_END; type++) {
if (chan->stream_topology) {
chan->default_streams[type] =
ast_stream_topology_get_first_stream_by_type(chan->stream_topology, type);
} else {
chan->default_streams[type] = NULL;
}
}
}
void ast_channel_internal_set_stream_topology(struct ast_channel *chan,
struct ast_stream_topology *topology)
{
ast_stream_topology_destroy(chan->stream_topology);
chan->stream_topology = topology;
channel_set_default_streams(chan);
}
void ast_channel_nativeformats_set(struct ast_channel *chan,
struct ast_format_cap *value)
{
ast_assert(chan != NULL);
ao2_replace(chan->nativeformats, value);
/* If chan->stream_topology is NULL, the channel is being destroyed
* and topology is destroyed.
*/
if (!chan->stream_topology) {
return;
}
if (!chan->tech || !(chan->tech->properties & AST_CHAN_TP_MULTISTREAM) || !value) {
struct ast_stream_topology *new_topology;
if (!value) {
new_topology = ast_stream_topology_create();
} else {
new_topology = ast_stream_topology_create_from_format_cap(value);
}
ast_channel_internal_set_stream_topology(chan, new_topology);
}
}
struct ast_framehook_list *ast_channel_framehooks(const struct ast_channel *chan)
{
return chan->framehooks;
@@ -1637,6 +1687,8 @@ void ast_channel_internal_cleanup(struct ast_channel *chan)
stasis_cp_single_unsubscribe(chan->topics);
chan->topics = NULL;
ast_channel_internal_set_stream_topology(chan, NULL);
}
void ast_channel_internal_finalize(struct ast_channel *chan)
@@ -1729,3 +1781,52 @@ enum ast_channel_error ast_channel_internal_errno(void)
return *error_code;
}
struct ast_stream_topology *ast_channel_get_stream_topology(
const struct ast_channel *chan)
{
ast_assert(chan != NULL);
return chan->stream_topology;
}
struct ast_stream_topology *ast_channel_set_stream_topology(struct ast_channel *chan,
struct ast_stream_topology *topology)
{
struct ast_stream_topology *new_topology;
ast_assert(chan != NULL);
/* A non-MULTISTREAM channel can't manipulate topology directly */
ast_assert(chan->tech != NULL && (chan->tech->properties & AST_CHAN_TP_MULTISTREAM));
/* Unless the channel is being destroyed, we always want a topology on
* it even if its empty.
*/
if (!topology) {
new_topology = ast_stream_topology_create();
} else {
new_topology = topology;
}
if (new_topology) {
ast_channel_internal_set_stream_topology(chan, new_topology);
}
return new_topology;
}
void ast_channel_internal_swap_stream_topology(struct ast_channel *chan1,
struct ast_channel *chan2)
{
struct ast_stream_topology *tmp_topology;
ast_assert(chan1 != NULL && chan2 != NULL);
tmp_topology = chan1->stream_topology;
chan1->stream_topology = chan2->stream_topology;
chan2->stream_topology = tmp_topology;
channel_set_default_streams(chan1);
channel_set_default_streams(chan2);
}