diff options
author | George Joseph <gjoseph@digium.com> | 2017-02-13 10:50:47 -0700 |
---|---|---|
committer | George Joseph <gjoseph@digium.com> | 2017-02-14 14:09:37 -0700 |
commit | bf2f091bbb2b099d6ca87e5fdd76efe45a209eb7 (patch) | |
tree | 3ebbbb4a3a9235f221bb0df50587e9873905b5f9 /main/channel_internal_api.c | |
parent | 6c4657e28ebf9cbe6d952750142d9631ff600657 (diff) |
stream: Add stream topology to channel
Adds topology set and get to channel.
ASTERISK-26790
Change-Id: Ic379ea82a9486fc79dbd8c4d95c29fa3b46424f4
Diffstat (limited to 'main/channel_internal_api.c')
-rw-r--r-- | main/channel_internal_api.c | 103 |
1 files changed, 102 insertions, 1 deletions
diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c index a0cbe8643..235b99604 100644 --- a/main/channel_internal_api.c +++ b/main/channel_internal_api.c @@ -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) +{ + 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); +} |