From 7b0e3b92fd49e5fbe406ef74336e164eb3f31b6e Mon Sep 17 00:00:00 2001 From: Kevin Harwell Date: Tue, 25 Apr 2017 11:49:16 -0500 Subject: bridge_simple: Added support for streams This patch is the first cut at adding stream support to the bridging framework. Changes were made to the framework that allows mapping of stream topologies to a bridge's supported media types. The first channel to enter a bridge initially defines the media types for a bridge (i.e. a one to one mapping is created between the bridge and the first channel). Subsequently added channels merge their media types into the bridge's adding to it when necessary. This allows channels with different sized topologies to map correctly to each other according to media type. The bridge drops any frame that does not have a matching index into a given write stream. For now though, bridge_simple will align its two channels according to size or first to join. Once both channels join the bridge the one with the most streams will indicate to the other channel to update its streams to be the same as that of the other. If both channels have the same number of streams then the first channel to join is chosen as the stream base. A topology change source was also added to a channel when a stream toplogy change request is made. This allows subsystems to know whether or not they initiated a change request. Thus avoiding potential recursive situations. ASTERISK-26966 #close Change-Id: I1eb5987921dd80c3cdcf52accc136393ca2d4163 --- tests/test_stream.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/test_stream.c b/tests/test_stream.c index 7eecf373b..a2a970181 100644 --- a/tests/test_stream.c +++ b/tests/test_stream.c @@ -1592,7 +1592,7 @@ AST_TEST_DEFINE(stream_topology_change_request_from_application_non_multistream) topology = ast_stream_topology_alloc(); ast_test_validate_cleanup(test, topology, res, done); - change_res = ast_channel_request_stream_topology_change(mock_channel, topology); + change_res = ast_channel_request_stream_topology_change(mock_channel, topology, NULL); ast_test_validate_cleanup(test, change_res == -1, res, done); ast_test_validate_cleanup(test, !pvt->indicated_change_request, res, done); @@ -1700,7 +1700,7 @@ AST_TEST_DEFINE(stream_topology_change_request_from_application) topology = ast_stream_topology_alloc(); ast_test_validate_cleanup(test, topology, res, done); - change_res = ast_channel_request_stream_topology_change(mock_channel, topology); + change_res = ast_channel_request_stream_topology_change(mock_channel, topology, NULL); ast_test_validate_cleanup(test, !change_res, res, done); ast_test_validate_cleanup(test, pvt->indicated_change_request, res, done); @@ -1830,6 +1830,97 @@ AST_TEST_DEFINE(format_cap_from_stream_topology) return AST_TEST_PASS; } +#define topology_append_stream(topology, name, type, res, label) \ + do { \ + struct ast_stream *__stream = ast_stream_alloc((name), (type)); \ + ast_test_validate_cleanup(test, __stream, res, label); \ + if (ast_stream_topology_append_stream((topology), __stream) < 0) { \ + ast_stream_free(__stream); \ + res = AST_TEST_FAIL; \ + goto label; \ + } \ + } while(0) + +AST_TEST_DEFINE(stream_topology_map_create) +{ + RAII_VAR(struct ast_stream_topology *, t0, NULL, ast_stream_topology_free); + + struct ast_vector_int types = { NULL }; + struct ast_vector_int v0 = { NULL }; + struct ast_vector_int v1 = { NULL }; + + enum ast_test_result_state res = AST_TEST_PASS; + + switch (cmd) { + case TEST_INIT: + info->name = "stream_topology_map_create"; + info->category = "/main/stream/"; + info->summary = "stream topology map creation unit test"; + info->description = + "Test that creating a stream topology map works"; + return AST_TEST_NOT_RUN; + case TEST_EXECUTE: + break; + } + + ast_test_validate(test, AST_VECTOR_INIT(&types, 5) == 0); + + /* Map a first topology and check that it mapped one to one */ + ast_test_validate_cleanup(test, (t0 = ast_stream_topology_alloc()), res, done); + topology_append_stream(t0, "audio", AST_MEDIA_TYPE_AUDIO, res, done); + topology_append_stream(t0, "video", AST_MEDIA_TYPE_VIDEO, res, done); + + ast_stream_topology_map(t0, &types, &v0, &v1); + ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&types) == 2, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&types, 0) == AST_MEDIA_TYPE_AUDIO, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&types, 1) == AST_MEDIA_TYPE_VIDEO, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v0, 0) == 0, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v0, 1) == 1, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v1, 0) == 0, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v1, 1) == 1, res, done); + + /* Map a second topology and check that it merged */ + ast_stream_topology_free(t0); + ast_test_validate_cleanup(test, (t0 = ast_stream_topology_alloc()), res, done); + topology_append_stream(t0, "video", AST_MEDIA_TYPE_VIDEO, res, done); + topology_append_stream(t0, "audio", AST_MEDIA_TYPE_AUDIO, res, done); + + ast_stream_topology_map(t0, &types, &v0, &v1); + ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&types) == 2, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&types, 0) == AST_MEDIA_TYPE_AUDIO, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&types, 1) == AST_MEDIA_TYPE_VIDEO, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v0, 0) == 1, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v0, 1) == 0, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v1, 0) == 1, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v1, 1) == 0, res, done); + + /* Map a third topology with more streams and check that it merged */ + ast_stream_topology_free(t0); + ast_test_validate_cleanup(test, (t0 = ast_stream_topology_alloc()), res, done); + topology_append_stream(t0, "video", AST_MEDIA_TYPE_VIDEO, res, done); + topology_append_stream(t0, "audio", AST_MEDIA_TYPE_AUDIO, res, done); + topology_append_stream(t0, "audio", AST_MEDIA_TYPE_AUDIO, res, done); + + ast_stream_topology_map(t0, &types, &v0, &v1); + ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&types) == 3, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&types, 0) == AST_MEDIA_TYPE_AUDIO, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&types, 1) == AST_MEDIA_TYPE_VIDEO, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&types, 2) == AST_MEDIA_TYPE_AUDIO, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v0, 0) == 1, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v0, 1) == 0, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v0, 2) == 2, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v1, 0) == 1, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v1, 1) == 0, res, done); + ast_test_validate_cleanup(test, AST_VECTOR_GET(&v1, 2) == 2, res, done); + +done: + AST_VECTOR_FREE(&v1); + AST_VECTOR_FREE(&v0); + AST_VECTOR_FREE(&types); + + return res; +} + static int unload_module(void) { AST_TEST_UNREGISTER(stream_create); @@ -1855,6 +1946,7 @@ static int unload_module(void) AST_TEST_UNREGISTER(stream_topology_change_request_from_application); AST_TEST_UNREGISTER(stream_topology_change_request_from_channel); AST_TEST_UNREGISTER(format_cap_from_stream_topology); + AST_TEST_UNREGISTER(stream_topology_map_create); return 0; } @@ -1882,6 +1974,7 @@ static int load_module(void) AST_TEST_REGISTER(stream_topology_change_request_from_application); AST_TEST_REGISTER(stream_topology_change_request_from_channel); AST_TEST_REGISTER(format_cap_from_stream_topology); + AST_TEST_REGISTER(stream_topology_map_create); return AST_MODULE_LOAD_SUCCESS; } -- cgit v1.2.3