<p>Richard Mudgett has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/5814">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">stream: Add ast_stream_topology_del_stream() and unit test.<br><br>Change-Id: If07e3c716a2e3ff85ae905c17572ea6ec3cdc1f9<br>---<br>M include/asterisk/stream.h<br>M main/stream.c<br>M tests/test_stream.c<br>3 files changed, 180 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/14/5814/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/include/asterisk/stream.h b/include/asterisk/stream.h<br>index fcee3e4..d31a0de 100644<br>--- a/include/asterisk/stream.h<br>+++ b/include/asterisk/stream.h<br>@@ -359,6 +359,21 @@<br> unsigned int position, struct ast_stream *stream);<br> <br> /*!<br>+ * \brief Delete a specified stream from the given topology.<br>+ * \since 15.0.0<br>+ *<br>+ * \param topology The topology of streams.<br>+ * \param position The topology position to delete.<br>+ *<br>+ * \retval 0 on success.<br>+ * \retval -1 on failure.<br>+ *<br>+ * \return Nothing<br>+ */<br>+int ast_stream_topology_del_stream(struct ast_stream_topology *topology,<br>+ unsigned int position);<br>+<br>+/*!<br> * \brief A helper function that, given a format capabilities structure,<br> * creates a topology and separates the media types in format_cap into<br> * separate streams.<br>diff --git a/main/stream.c b/main/stream.c<br>index fb14693..b617744 100644<br>--- a/main/stream.c<br>+++ b/main/stream.c<br>@@ -349,6 +349,29 @@<br> return AST_VECTOR_REPLACE(&topology->streams, position, stream);<br> }<br> <br>+int ast_stream_topology_del_stream(struct ast_stream_topology *topology,<br>+ unsigned int position)<br>+{<br>+ struct ast_stream *stream;<br>+<br>+ ast_assert(topology != NULL);<br>+<br>+ if (AST_VECTOR_SIZE(&topology->streams) <= position) {<br>+ return -1;<br>+ }<br>+<br>+ stream = AST_VECTOR_REMOVE_ORDERED(&topology->streams, position);<br>+ ast_stream_free(stream);<br>+<br>+ /* Fix up higher stream position indices */<br>+ for (; position < AST_VECTOR_SIZE(&topology->streams); ++position) {<br>+ stream = AST_VECTOR_GET(&topology->streams, position);<br>+ stream->position = position;<br>+ }<br>+<br>+ return 0;<br>+}<br>+<br> struct ast_stream_topology *ast_stream_topology_create_from_format_cap(<br> struct ast_format_cap *cap)<br> {<br>diff --git a/tests/test_stream.c b/tests/test_stream.c<br>index a2a9701..cf3d2e3 100644<br>--- a/tests/test_stream.c<br>+++ b/tests/test_stream.c<br>@@ -529,6 +529,146 @@<br> return AST_TEST_PASS;<br> }<br> <br>+static int check_stream_positions(struct ast_test *test, const struct ast_stream_topology *topology)<br>+{<br>+ const struct ast_stream *stream;<br>+ int idx;<br>+ int pos;<br>+ enum ast_media_type type;<br>+<br>+ for (idx = 0; idx < ast_stream_topology_get_count(topology); ++idx) {<br>+ stream = ast_stream_topology_get_stream(topology, idx);<br>+ pos = ast_stream_get_position(stream);<br>+ if (idx != pos) {<br>+ type = ast_stream_get_type(stream);<br>+ ast_test_status_update(test, "Failed: '%s' stream says it is at position %d instead of %d\n",<br>+ ast_codec_media_type2str(type), pos, idx);<br>+ return -1;<br>+ }<br>+ }<br>+ return 0;<br>+}<br>+<br>+AST_TEST_DEFINE(stream_topology_del_stream)<br>+{<br>+ RAII_VAR(struct ast_stream_topology *, topology, NULL, ast_stream_topology_free);<br>+ struct ast_stream *stream;<br>+ enum ast_media_type type;<br>+ int idx;<br>+<br>+ switch (cmd) {<br>+ case TEST_INIT:<br>+ info->name = "stream_topology_del_stream";<br>+ info->category = "/main/stream/";<br>+ info->summary = "stream topology stream delete unit test";<br>+ info->description =<br>+ "Test that deleting streams at a specific position in a topology works";<br>+ return AST_TEST_NOT_RUN;<br>+ case TEST_EXECUTE:<br>+ break;<br>+ }<br>+<br>+ topology = ast_stream_topology_alloc();<br>+ if (!topology) {<br>+ ast_test_status_update(test, "Failed to create media stream topology\n");<br>+ return AST_TEST_FAIL;<br>+ }<br>+<br>+ /* Create streams */<br>+ for (type = AST_MEDIA_TYPE_UNKNOWN; type < AST_MEDIA_TYPE_END; ++type) {<br>+ stream = ast_stream_alloc(ast_codec_media_type2str(type), type);<br>+ if (!stream) {<br>+ ast_test_status_update(test, "Failed to create '%s' stream for testing stream topology\n",<br>+ ast_codec_media_type2str(type));<br>+ return AST_TEST_FAIL;<br>+ }<br>+ if (ast_stream_topology_append_stream(topology, stream) == -1) {<br>+ ast_test_status_update(test, "Failed to append '%s' stream to topology\n",<br>+ ast_codec_media_type2str(type));<br>+ ast_stream_free(stream);<br>+ return AST_TEST_FAIL;<br>+ }<br>+ }<br>+<br>+ /* Check initial stream positions and types for sanity. */<br>+ type = AST_MEDIA_TYPE_UNKNOWN;<br>+ for (idx = 0; idx < ast_stream_topology_get_count(topology); ++idx, ++type) {<br>+ stream = ast_stream_topology_get_stream(topology, idx);<br>+ if (type != ast_stream_get_type(stream)) {<br>+ ast_test_status_update(test, "Initial topology types failed: Expected:%s Got:%s\n",<br>+ ast_codec_media_type2str(type),<br>+ ast_codec_media_type2str(ast_stream_get_type(stream)));<br>+ return AST_TEST_FAIL;<br>+ }<br>+ }<br>+ if (check_stream_positions(test, topology)) {<br>+ ast_test_status_update(test, "Initial topology positions failed.\n");<br>+ return AST_TEST_FAIL;<br>+ }<br>+<br>+ /* Try to delete outside of topology size */<br>+ if (!ast_stream_topology_del_stream(topology, ast_stream_topology_get_count(topology))) {<br>+ ast_test_status_update(test, "Deleting stream outside of topology succeeded!\n");<br>+ return AST_TEST_FAIL;<br>+ }<br>+<br>+ /* Try to delete the last topology stream */<br>+ if (ast_stream_topology_del_stream(topology, ast_stream_topology_get_count(topology) - 1)) {<br>+ ast_test_status_update(test, "Failed deleting last stream of topology.\n");<br>+ return AST_TEST_FAIL;<br>+ }<br>+ if (check_stream_positions(test, topology)) {<br>+ ast_test_status_update(test, "Last stream delete topology positions failed.\n");<br>+ return AST_TEST_FAIL;<br>+ }<br>+ stream = ast_stream_topology_get_stream(topology, ast_stream_topology_get_count(topology) - 1);<br>+ type = ast_stream_get_type(stream);<br>+ if (type != AST_MEDIA_TYPE_END - 2) {<br>+ ast_test_status_update(test, "Last stream delete types failed: Expected:%s Got:%s\n",<br>+ ast_codec_media_type2str(AST_MEDIA_TYPE_END - 2),<br>+ ast_codec_media_type2str(type));<br>+ return AST_TEST_FAIL;<br>+ }<br>+<br>+ /* Try to delete the second stream in the topology */<br>+ if (ast_stream_topology_del_stream(topology, 1)) {<br>+ ast_test_status_update(test, "Failed deleting second stream in topology.\n");<br>+ return AST_TEST_FAIL;<br>+ }<br>+ if (check_stream_positions(test, topology)) {<br>+ ast_test_status_update(test, "Second stream delete topology positions failed.\n");<br>+ return AST_TEST_FAIL;<br>+ }<br>+ stream = ast_stream_topology_get_stream(topology, 1);<br>+ type = ast_stream_get_type(stream);<br>+ if (type != AST_MEDIA_TYPE_UNKNOWN + 2) {<br>+ ast_test_status_update(test, "Second stream delete types failed: Expected:%s Got:%s\n",<br>+ ast_codec_media_type2str(AST_MEDIA_TYPE_UNKNOWN + 2),<br>+ ast_codec_media_type2str(type));<br>+ return AST_TEST_FAIL;<br>+ }<br>+<br>+ /* Try to delete the first stream in the topology */<br>+ if (ast_stream_topology_del_stream(topology, 0)) {<br>+ ast_test_status_update(test, "Failed deleting first stream in topology.\n");<br>+ return AST_TEST_FAIL;<br>+ }<br>+ if (check_stream_positions(test, topology)) {<br>+ ast_test_status_update(test, "First stream delete topology positions failed.\n");<br>+ return AST_TEST_FAIL;<br>+ }<br>+ stream = ast_stream_topology_get_stream(topology, 0);<br>+ type = ast_stream_get_type(stream);<br>+ if (type != AST_MEDIA_TYPE_UNKNOWN + 2) {<br>+ ast_test_status_update(test, "First stream delete types failed: Expected:%s Got:%s\n",<br>+ ast_codec_media_type2str(AST_MEDIA_TYPE_UNKNOWN + 2),<br>+ ast_codec_media_type2str(type));<br>+ return AST_TEST_FAIL;<br>+ }<br>+<br>+ return AST_TEST_PASS;<br>+}<br>+<br> AST_TEST_DEFINE(stream_topology_create_from_format_cap)<br> {<br> RAII_VAR(struct ast_stream_topology *, topology, NULL, ast_stream_topology_free);<br>@@ -1933,6 +2073,7 @@<br> AST_TEST_UNREGISTER(stream_topology_clone);<br> AST_TEST_UNREGISTER(stream_topology_append_stream);<br> AST_TEST_UNREGISTER(stream_topology_set_stream);<br>+ AST_TEST_UNREGISTER(stream_topology_del_stream);<br> AST_TEST_UNREGISTER(stream_topology_create_from_format_cap);<br> AST_TEST_UNREGISTER(stream_topology_get_first_stream_by_type);<br> AST_TEST_UNREGISTER(stream_topology_create_from_channel_nativeformats);<br>@@ -1961,6 +2102,7 @@<br> AST_TEST_REGISTER(stream_topology_clone);<br> AST_TEST_REGISTER(stream_topology_append_stream);<br> AST_TEST_REGISTER(stream_topology_set_stream);<br>+ AST_TEST_REGISTER(stream_topology_del_stream);<br> AST_TEST_REGISTER(stream_topology_create_from_format_cap);<br> AST_TEST_REGISTER(stream_topology_get_first_stream_by_type);<br> AST_TEST_REGISTER(stream_topology_create_from_channel_nativeformats);<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/5814">change 5814</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/5814"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: If07e3c716a2e3ff85ae905c17572ea6ec3cdc1f9 </div>
<div style="display:none"> Gerrit-Change-Number: 5814 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Richard Mudgett <rmudgett@digium.com> </div>