diff options
author | Jenkins2 <jenkins2@gerrit.asterisk.org> | 2017-06-16 11:51:41 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2017-06-16 11:51:41 -0500 |
commit | d81293a5ddd545c8b2b3683306a17af91e41c102 (patch) | |
tree | 8a07ef3f636fcce9f49f46477091ee7e36400643 | |
parent | 2f684eb6a5db2b84145fd539f4112f59dffc4b43 (diff) | |
parent | a95584d07999035de85da3a84a422bb3c6475122 (diff) |
Merge changes from topic 'sdp_api_adjustments'
* changes:
SDP: Set the remote c= line in RTP instance.
SDP: Add t= line in sdp_create_from_state()
stream: Ignore declined streams for some topology calls.
-rw-r--r-- | include/asterisk/sdp_state.h | 4 | ||||
-rw-r--r-- | include/asterisk/stream.h | 9 | ||||
-rw-r--r-- | main/sdp_state.c | 45 | ||||
-rw-r--r-- | main/stream.c | 12 | ||||
-rw-r--r-- | tests/test_stream.c | 85 |
5 files changed, 131 insertions, 24 deletions
diff --git a/include/asterisk/sdp_state.h b/include/asterisk/sdp_state.h index c2122fbce..b8209e1d5 100644 --- a/include/asterisk/sdp_state.h +++ b/include/asterisk/sdp_state.h @@ -146,6 +146,10 @@ const void *ast_sdp_state_get_local_sdp_impl(struct ast_sdp_state *sdp_state); * \param sdp_state * \param sdp * + * \note It is assumed that the passed in SDP has been checked for sanity + * already. e.g., There are no syntax errors, a c= line is reachable for + * each m= line, etc... + * * \retval 0 Success * \retval non-0 Failure * diff --git a/include/asterisk/stream.h b/include/asterisk/stream.h index 14d624fb2..00169a3f1 100644 --- a/include/asterisk/stream.h +++ b/include/asterisk/stream.h @@ -401,8 +401,11 @@ struct ast_stream_topology *ast_stream_topology_create_from_format_cap( struct ast_format_cap *cap); /*! - * \brief A helper function that, given a stream topology, creates a format - * capabilities structure containing all formats from all streams. + * \brief Create a format capabilities structure representing the topology. + * + * \details + * A helper function that, given a stream topology, creates a format + * capabilities structure containing all formats from all active streams. * * \param topology The topology of streams * @@ -417,7 +420,7 @@ struct ast_format_cap *ast_format_cap_from_stream_topology( struct ast_stream_topology *topology); /*! - * \brief Gets the first stream of a specific type from the topology + * \brief Gets the first active stream of a specific type from the topology * * \param topology The topology of streams * \param type The media type diff --git a/main/sdp_state.c b/main/sdp_state.c index 00f147f47..f27da211b 100644 --- a/main/sdp_state.c +++ b/main/sdp_state.c @@ -997,11 +997,32 @@ static void update_rtp_after_merge(const struct ast_sdp_state *state, const struct ast_sdp *remote_sdp, const struct ast_sdp_m_line *remote_m_line) { + struct ast_sdp_c_line *c_line; + struct ast_sockaddr *addrs; + if (!rtp) { /* This is a dummy stream */ return; } + c_line = remote_m_line->c_line; + if (!c_line) { + c_line = remote_sdp->c_line; + } + /* + * There must be a c= line somewhere but that would be an error by + * the far end that should have been caught by a validation check + * before we processed the SDP. + */ + ast_assert(c_line != NULL); + + if (ast_sockaddr_resolve(&addrs, c_line->address, PARSE_PORT_FORBID, AST_AF_UNSPEC) > 0) { + /* Apply connection information to the RTP instance */ + ast_sockaddr_set_port(addrs, remote_m_line->port); + ast_rtp_instance_set_remote_address(rtp->instance, addrs); + ast_free(addrs); + } + if (ast_sdp_options_get_rtcp_mux(options) && ast_sdp_m_find_attribute(remote_m_line, "rtcp-mux", -1)) { ast_rtp_instance_set_prop(rtp->instance, AST_RTP_PROPERTY_RTCP, @@ -1011,9 +1032,7 @@ static void update_rtp_after_merge(const struct ast_sdp_state *state, AST_RTP_INSTANCE_RTCP_STANDARD); } - if (ast_sdp_options_get_ice(options) == AST_SDP_ICE_ENABLED_STANDARD) { - update_ice(state, rtp->instance, options, remote_sdp, remote_m_line); - } + update_ice(state, rtp->instance, options, remote_sdp, remote_m_line); } /*! @@ -1066,12 +1085,19 @@ static void update_udptl_after_merge(const struct ast_sdp_state *state, struct s } } - c_line = remote_sdp->c_line; - if (remote_m_line->c_line) { - c_line = remote_m_line->c_line; + c_line = remote_m_line->c_line; + if (!c_line) { + c_line = remote_sdp->c_line; } + /* + * There must be a c= line somewhere but that would be an error by + * the far end that should have been caught by a validation check + * before we processed the SDP. + */ + ast_assert(c_line != NULL); if (ast_sockaddr_resolve(&addrs, c_line->address, PARSE_PORT_FORBID, AST_AF_UNSPEC) > 0) { + /* Apply connection information to the UDPTL instance */ ast_sockaddr_set_port(addrs, remote_m_line->port); ast_udptl_set_peer(udptl->instance, addrs); ast_free(addrs); @@ -1734,13 +1760,16 @@ static struct ast_sdp *sdp_create_from_state(const struct ast_sdp_state *sdp_sta if (!c_line) { goto error; } - s_line = ast_sdp_s_alloc(options->sdpsession); if (!s_line) { goto error; } + t_line = ast_sdp_t_alloc(0, 0); + if (!t_line) { + goto error; + } - sdp = ast_sdp_alloc(o_line, c_line, s_line, NULL); + sdp = ast_sdp_alloc(o_line, c_line, s_line, t_line); if (!sdp) { goto error; } diff --git a/main/stream.c b/main/stream.c index b61774474..20179f331 100644 --- a/main/stream.c +++ b/main/stream.c @@ -437,9 +437,11 @@ struct ast_format_cap *ast_format_cap_from_stream_topology( } for (i = 0; i < AST_VECTOR_SIZE(&topology->streams); i++) { - struct ast_stream *stream = AST_VECTOR_GET(&topology->streams, i); + struct ast_stream *stream; - if (!stream->formats) { + stream = AST_VECTOR_GET(&topology->streams, i); + if (!stream->formats + || stream->state == AST_STREAM_STATE_REMOVED) { continue; } @@ -458,9 +460,11 @@ struct ast_stream *ast_stream_topology_get_first_stream_by_type( ast_assert(topology != NULL); for (i = 0; i < AST_VECTOR_SIZE(&topology->streams); i++) { - struct ast_stream *stream = AST_VECTOR_GET(&topology->streams, i); + struct ast_stream *stream; - if (stream->type == type) { + stream = AST_VECTOR_GET(&topology->streams, i); + if (stream->type == type + && stream->state != AST_STREAM_STATE_REMOVED) { return stream; } } diff --git a/tests/test_stream.c b/tests/test_stream.c index cf3d2e365..fdb988584 100644 --- a/tests/test_stream.c +++ b/tests/test_stream.c @@ -755,7 +755,12 @@ AST_TEST_DEFINE(stream_topology_create_from_format_cap) AST_TEST_DEFINE(stream_topology_get_first_stream_by_type) { RAII_VAR(struct ast_stream_topology *, topology, NULL, ast_stream_topology_free); - struct ast_stream *first_stream, *second_stream, *third_stream, *fourth_stream; + struct ast_stream *first_stream; + struct ast_stream *second_stream; + struct ast_stream *third_stream; + struct ast_stream *fourth_stream; + struct ast_stream *fifth_stream; + struct ast_stream *sixth_stream; switch (cmd) { case TEST_INIT: @@ -780,6 +785,7 @@ AST_TEST_DEFINE(stream_topology_get_first_stream_by_type) ast_test_status_update(test, "Failed to create an audio stream for testing stream topology\n"); return AST_TEST_FAIL; } + ast_stream_set_state(first_stream, AST_STREAM_STATE_REMOVED); if (ast_stream_topology_append_stream(topology, first_stream) == -1) { ast_test_status_update(test, "Failed to append a perfectly good stream to a topology\n"); @@ -799,9 +805,9 @@ AST_TEST_DEFINE(stream_topology_get_first_stream_by_type) return AST_TEST_FAIL; } - third_stream = ast_stream_alloc("video", AST_MEDIA_TYPE_VIDEO); + third_stream = ast_stream_alloc("audio3", AST_MEDIA_TYPE_AUDIO); if (!third_stream) { - ast_test_status_update(test, "Failed to create a video stream for testing stream topology\n"); + ast_test_status_update(test, "Failed to create a third audio stream for testing stream topology\n"); return AST_TEST_FAIL; } @@ -811,11 +817,12 @@ AST_TEST_DEFINE(stream_topology_get_first_stream_by_type) return AST_TEST_FAIL; } - fourth_stream = ast_stream_alloc("video2", AST_MEDIA_TYPE_VIDEO); + fourth_stream = ast_stream_alloc("video", AST_MEDIA_TYPE_VIDEO); if (!fourth_stream) { - ast_test_status_update(test, "Failed to create a second video stream for testing stream topology\n"); + ast_test_status_update(test, "Failed to create a video stream for testing stream topology\n"); return AST_TEST_FAIL; } + ast_stream_set_state(fourth_stream, AST_STREAM_STATE_REMOVED); if (ast_stream_topology_append_stream(topology, fourth_stream) == -1) { ast_test_status_update(test, "Failed to append a perfectly good stream to a topology\n"); @@ -823,12 +830,36 @@ AST_TEST_DEFINE(stream_topology_get_first_stream_by_type) return AST_TEST_FAIL; } - if (ast_stream_topology_get_first_stream_by_type(topology, AST_MEDIA_TYPE_AUDIO) != first_stream) { + fifth_stream = ast_stream_alloc("video2", AST_MEDIA_TYPE_VIDEO); + if (!fifth_stream) { + ast_test_status_update(test, "Failed to create a second video stream for testing stream topology\n"); + return AST_TEST_FAIL; + } + + if (ast_stream_topology_append_stream(topology, fifth_stream) == -1) { + ast_test_status_update(test, "Failed to append a perfectly good stream to a topology\n"); + ast_stream_free(fifth_stream); + return AST_TEST_FAIL; + } + + sixth_stream = ast_stream_alloc("video3", AST_MEDIA_TYPE_VIDEO); + if (!sixth_stream) { + ast_test_status_update(test, "Failed to create a third video stream for testing stream topology\n"); + return AST_TEST_FAIL; + } + + if (ast_stream_topology_append_stream(topology, sixth_stream) == -1) { + ast_test_status_update(test, "Failed to append a perfectly good stream to a topology\n"); + ast_stream_free(sixth_stream); + return AST_TEST_FAIL; + } + + if (ast_stream_topology_get_first_stream_by_type(topology, AST_MEDIA_TYPE_AUDIO) != second_stream) { ast_test_status_update(test, "Retrieved first audio stream from topology but it is not the correct one\n"); return AST_TEST_FAIL; } - if (ast_stream_topology_get_first_stream_by_type(topology, AST_MEDIA_TYPE_VIDEO) != third_stream) { + if (ast_stream_topology_get_first_stream_by_type(topology, AST_MEDIA_TYPE_VIDEO) != fifth_stream) { ast_test_status_update(test, "Retrieved first video stream from topology but it is not the correct one\n"); return AST_TEST_FAIL; } @@ -1918,6 +1949,8 @@ AST_TEST_DEFINE(format_cap_from_stream_topology) RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup); RAII_VAR(struct ast_format_cap *, stream_caps, NULL, ao2_cleanup); struct ast_stream_topology *topology; + struct ast_stream *stream; + struct ast_format_cap *new_cap; switch (cmd) { case TEST_INIT: @@ -1938,12 +1971,12 @@ AST_TEST_DEFINE(format_cap_from_stream_topology) } if (ast_format_cap_append(caps, ast_format_ulaw, 0)) { - ast_test_status_update(test, "Failed to append a ulaw format to capabilities for channel nativeformats\n"); + ast_test_status_update(test, "Failed to append ulaw format to capabilities\n"); return AST_TEST_FAIL; } if (ast_format_cap_append(caps, ast_format_h264, 0)) { - ast_test_status_update(test, "Failed to append an h264 format to capabilities for channel nativeformats\n"); + ast_test_status_update(test, "Failed to append h264 format to capabilities\n"); return AST_TEST_FAIL; } @@ -1953,6 +1986,40 @@ AST_TEST_DEFINE(format_cap_from_stream_topology) return AST_TEST_FAIL; } + /* + * Append declined stream with formats that should not be included + * in combined topology caps. + */ + stream = ast_stream_alloc("audio", AST_MEDIA_TYPE_AUDIO); + if (!stream) { + ast_test_status_update(test, "Failed to create an audio stream for testing stream topology\n"); + ast_stream_topology_free(topology); + return AST_TEST_FAIL; + } + ast_stream_set_state(stream, AST_STREAM_STATE_REMOVED); + new_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT); + if (!new_cap) { + ast_test_status_update(test, "Could not allocate an empty format capabilities structure\n"); + ast_stream_free(stream); + ast_stream_topology_free(topology); + return AST_TEST_FAIL; + } + if (ast_format_cap_append(new_cap, ast_format_alaw, 0)) { + ast_test_status_update(test, "Failed to append alaw format to capabilities\n"); + ao2_cleanup(new_cap); + ast_stream_free(stream); + ast_stream_topology_free(topology); + return AST_TEST_FAIL; + } + ast_stream_set_formats(stream, new_cap); + ao2_cleanup(new_cap); + if (ast_stream_topology_append_stream(topology, stream) == -1) { + ast_test_status_update(test, "Failed to append a perfectly good stream to a topology\n"); + ast_stream_free(stream); + ast_stream_topology_free(topology); + return AST_TEST_FAIL; + } + stream_caps = ast_format_cap_from_stream_topology(topology); if (!stream_caps) { ast_test_status_update(test, "Failed to create a format capabilities from a stream topology\n"); |