summaryrefslogtreecommitdiff
path: root/main/stream.c
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2017-05-30 09:12:47 -0500
committerJoshua Colp <jcolp@digium.com>2017-06-28 18:36:29 +0000
commit45df25a579edd5423c9d319758d109a74fe8ef33 (patch)
treef7138bb2b13915f0542c5c6fff30b4c73025eb71 /main/stream.c
parenta48d3e4d31c8060856d785fca00c5213d5e012bc (diff)
chan_pjsip: Add support for multiple streams of the same type.
The stream topology (list of streams and order) is now stored with the configured PJSIP endpoints and used during the negotiation process. Media negotiation state information has been changed to be stored in a separate object. Two of these objects exist at any one time on a session. The active media state information is what was previously negotiated and the pending media state information is what the media state will become if negotiation succeeds. Streams and other state information is stored in this object using the index (or position) of each individual stream for easy lookup. The ability for a media type handler to specify a callback for writing has been added as well as the ability to add file descriptors with a callback which is invoked when data is available to be read on them. This allows media logic to live outside of the chan_pjsip module. Direct media has been changed so that only the first audio and video stream are directly connected. In the future once the RTP engine glue API has been updated to know about streams each individual stream can be directly connected as appropriate. Media negotiation itself will currently answer all the provided streams on an offer within configured limits and on an offer will use the topology created as a result of the disallow/allow codec lines. If a stream has been removed or declined we will now mark it as such within the resulting SDP. Applications can now also request that the stream topology change. If we are told to do so we will limit any provided formats to the ones configured on the endpoint and send a re-invite with the new topology. Two new configuration options have also been added to PJSIP endpoints: max_audio_streams: determines the maximum number of audio streams to offer/accept from an endpoint. Defaults to 1. max_video_streams: determines the maximum number of video streams to offer/accept from an endpoint. Defaults to 1. ASTERISK-27076 Change-Id: I8afd8dd2eb538806a39b887af0abd046266e14c7
Diffstat (limited to 'main/stream.c')
-rw-r--r--main/stream.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/main/stream.c b/main/stream.c
index 20179f331..093cd5450 100644
--- a/main/stream.c
+++ b/main/stream.c
@@ -284,6 +284,53 @@ struct ast_stream_topology *ast_stream_topology_clone(
return new_topology;
}
+int ast_stream_topology_equal(const struct ast_stream_topology *left,
+ const struct ast_stream_topology *right)
+{
+ int index;
+
+ ast_assert(left != NULL);
+ ast_assert(right != NULL);
+
+ if (ast_stream_topology_get_count(left) != ast_stream_topology_get_count(right)) {
+ return 0;
+ }
+
+ for (index = 0; index < ast_stream_topology_get_count(left); ++index) {
+ const struct ast_stream *left_stream = ast_stream_topology_get_stream(left, index);
+ const struct ast_stream *right_stream = ast_stream_topology_get_stream(right, index);
+
+ if (ast_stream_get_type(left_stream) != ast_stream_get_type(right_stream)) {
+ return 0;
+ }
+
+ if (ast_stream_get_state(left_stream) != ast_stream_get_state(right_stream)) {
+ return 0;
+ }
+
+ if (!ast_stream_get_formats(left_stream) && ast_stream_get_formats(right_stream) &&
+ ast_format_cap_count(ast_stream_get_formats(right_stream))) {
+ /* A NULL format capabilities and an empty format capabilities are the same, as they have
+ * no formats inside. If one does though... they are not equal.
+ */
+ return 0;
+ } else if (!ast_stream_get_formats(right_stream) && ast_stream_get_formats(left_stream) &&
+ ast_format_cap_count(ast_stream_get_formats(left_stream))) {
+ return 0;
+ } else if (ast_stream_get_formats(left_stream) && ast_stream_get_formats(right_stream) &&
+ !ast_format_cap_identical(ast_stream_get_formats(left_stream), ast_stream_get_formats(right_stream))) {
+ /* But if both are actually present we need to do an actual identical check. */
+ return 0;
+ }
+
+ if (strcmp(ast_stream_get_name(left_stream), ast_stream_get_name(right_stream))) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
void ast_stream_topology_free(struct ast_stream_topology *topology)
{
if (!topology) {