diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c
index 23dc548467d3246681b83283d1e6d752203d7ed6..46b27f104206ca0053324c8c5d558dd5e842856b 100644
--- a/bridges/bridge_softmix.c
+++ b/bridges/bridge_softmix.c
@@ -2159,15 +2159,7 @@ static void softmix_bridge_stream_topology_changed(struct ast_bridge *bridge, st
 		ast_bridge_channel_lock(participant);
 		ast_channel_lock(participant->chan);
 
-		topology = ast_channel_get_stream_topology(participant->chan);
-		if (topology) {
-			/*
-			 * Sigh.  We have to clone to avoid deadlock in
-			 * map_source_to_destinations() because topology
-			 * is not an ao2 object.
-			 */
-			topology = ast_stream_topology_clone(topology);
-		}
+		topology = ao2_bump(ast_channel_get_stream_topology(participant->chan));
 		if (!topology) {
 			/* Oh, my, we are in trouble. */
 			ast_channel_unlock(participant->chan);
diff --git a/include/asterisk/stream.h b/include/asterisk/stream.h
index 0a5550b5ee59030ae19d98638b36cb2c9b417f6d..ade740d19da84062a29562db59b3848779bd3a48 100644
--- a/include/asterisk/stream.h
+++ b/include/asterisk/stream.h
@@ -306,6 +306,8 @@ void ast_stream_set_rtp_codecs(struct ast_stream *stream, struct ast_rtp_codecs
  * \retval NULL failure
  *
  * \since 15
+ *
+ * \note This returns an ao2 refcounted object
  */
 struct ast_stream_topology *ast_stream_topology_alloc(void);
 
@@ -318,6 +320,8 @@ struct ast_stream_topology *ast_stream_topology_alloc(void);
  * \retval NULL failure
  *
  * \since 15
+ *
+ * \note This returns an ao2 refcounted object
  */
 struct ast_stream_topology *ast_stream_topology_clone(
 	const struct ast_stream_topology *topology);
@@ -337,7 +341,7 @@ int ast_stream_topology_equal(const struct ast_stream_topology *left,
 	const struct ast_stream_topology *right);
 
 /*!
- * \brief Destroy a stream topology
+ * \brief Unreference and destroy a stream topology
  *
  * \param topology The topology of streams
  *
diff --git a/main/stream.c b/main/stream.c
index dd3e765f6447ea6c805acd70458b2ed5a46de15e..47415bffffb74d7702656de76ab67c018c5b7abb 100644
--- a/main/stream.c
+++ b/main/stream.c
@@ -344,18 +344,26 @@ void ast_stream_set_rtp_codecs(struct ast_stream *stream, struct ast_rtp_codecs
 	stream->rtp_codecs = rtp_codecs;
 }
 
+static void stream_topology_destroy(void *data)
+{
+	struct ast_stream_topology *topology = data;
+
+	AST_VECTOR_CALLBACK_VOID(&topology->streams, ast_stream_free);
+	AST_VECTOR_FREE(&topology->streams);
+}
+
 #define TOPOLOGY_INITIAL_STREAM_COUNT 2
 struct ast_stream_topology *ast_stream_topology_alloc(void)
 {
 	struct ast_stream_topology *topology;
 
-	topology = ast_calloc(1, sizeof(*topology));
+	topology = ao2_alloc_options(sizeof(*topology), stream_topology_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
 	if (!topology) {
 		return NULL;
 	}
 
 	if (AST_VECTOR_INIT(&topology->streams, TOPOLOGY_INITIAL_STREAM_COUNT)) {
-		ast_free(topology);
+		ao2_ref(topology, -1);
 		topology = NULL;
 	}
 
@@ -440,13 +448,7 @@ int ast_stream_topology_equal(const struct ast_stream_topology *left,
 
 void ast_stream_topology_free(struct ast_stream_topology *topology)
 {
-	if (!topology) {
-		return;
-	}
-
-	AST_VECTOR_CALLBACK_VOID(&topology->streams, ast_stream_free);
-	AST_VECTOR_FREE(&topology->streams);
-	ast_free(topology);
+	ao2_cleanup(topology);
 }
 
 int ast_stream_topology_append_stream(struct ast_stream_topology *topology, struct ast_stream *stream)