diff --git a/bridges/bridge_native_rtp.c b/bridges/bridge_native_rtp.c
index 639b8946c69692f64e7c376e76c7e6fb6ba04320..27d8d77cac869ff8af1f1054b24cb28107ccd781 100644
--- a/bridges/bridge_native_rtp.c
+++ b/bridges/bridge_native_rtp.c
@@ -183,89 +183,10 @@ static int native_rtp_bridge_start(struct ast_bridge *bridge, struct ast_channel
 	return 0;
 }
 
-/*!
- * \internal
- * \brief Given a bridge channel, get its RTP instance
- *
- * The returned ast_rtp_instance has its refcount bumped.
- *
- * \param bridge_channel Take a guess
- * \retval NULL No RTP instance on this bridge channel
- * \retval non-NULL The RTP instance on this bridge channel
- */
-static struct ast_rtp_instance *bridge_channel_get_rtp_instance(struct ast_bridge_channel *bridge_channel)
-{
-	struct ast_rtp_glue *glue;
-	struct ast_rtp_instance *instance;
-
-	glue = ast_rtp_instance_get_glue(ast_channel_tech(bridge_channel->chan)->type);
-	if (!glue) {
-		return NULL;
-	}
-
-	glue->get_rtp_info(bridge_channel->chan, &instance);
-	return instance;
-}
-
-/*!
- * \internal
- * \brief Determine which two channels are bridged together
- *
- * Because of the nature of swapping, when the time comes for a channel to
- * leave a native RTP bridge, it may be that there are more than two channels
- * in the list of bridge channels. Therefore, it is important to correctly
- * determine which two channels were bridged together.
- *
- * \param bridge The involved bridge
- * \param leaving The bridge channel that is leaving the native RTP bridge
- * \param[out] c0 The first bridged channel
- * \param[out] c1 The second bridged channel
- */
-static void find_bridged_channels(struct ast_bridge *bridge, struct ast_bridge_channel *leaving,
-		struct ast_bridge_channel **c0, struct ast_bridge_channel **c1)
-{
-	RAII_VAR(struct ast_rtp_instance *, leaving_instance, bridge_channel_get_rtp_instance(leaving), ao2_cleanup);
-	struct ast_bridge_channel *iter;
-
-	if (!leaving_instance) {
-		return;
-	}
-
-	AST_LIST_TRAVERSE(&bridge->channels, iter, entry) {
-		RAII_VAR(struct ast_rtp_instance *, instance, NULL, ao2_cleanup);
-
-		if (iter == leaving) {
-			continue;
-		}
-
-		instance = bridge_channel_get_rtp_instance(iter);
-		if (!instance) {
-			continue;
-		}
-
-		if (instance == ast_rtp_instance_get_bridged(leaving_instance)) {
-			break;
-		}
-	}
-	*c0 = leaving;
-	*c1 = iter;
-	return;
-}
-
-/*!
- * \internal
- * \brief Stop native RTP bridging of two channels
- *
- * \param bridge The bridge that had native RTP bridging happening on it
- * \param target If remote RTP bridging, the channel that is placed on hold.
- * \param leaving If this is called because a channel is leaving, this is the
- * bridge channel that is leaving the bridge
- */
-static void native_rtp_bridge_stop(struct ast_bridge *bridge, struct ast_channel *target,
-		struct ast_bridge_channel *leaving)
+static void native_rtp_bridge_stop(struct ast_bridge *bridge, struct ast_channel *target)
 {
-	struct ast_bridge_channel *c0 = NULL;
-	struct ast_bridge_channel *c1 = NULL;
+	struct ast_bridge_channel *c0 = AST_LIST_FIRST(&bridge->channels);
+	struct ast_bridge_channel *c1 = AST_LIST_LAST(&bridge->channels);
 	enum ast_rtp_glue_result native_type;
 	struct ast_rtp_glue *glue0, *glue1 = NULL;
 	RAII_VAR(struct ast_rtp_instance *, instance0, NULL, ao2_cleanup);
@@ -273,17 +194,7 @@ static void native_rtp_bridge_stop(struct ast_bridge *bridge, struct ast_channel
 	RAII_VAR(struct ast_rtp_instance *, vinstance0, NULL, ao2_cleanup);
 	RAII_VAR(struct ast_rtp_instance *, vinstance1, NULL, ao2_cleanup);
 
-	if (bridge->num_channels == 2) {
-		c0 = AST_LIST_FIRST(&bridge->channels);
-		c1 = AST_LIST_LAST(&bridge->channels);
-	} else if (bridge->num_channels > 2) {
-		/* When a channel leaves a native RTP bridge, it is possible for
-		 * more channels to exist in the bridge than when the RTP bridge
-		 * was started. Thus we need to determine which two channels were
-		 * bridged based on the leaving channel
-		 */
-		find_bridged_channels(bridge, leaving, &c0, &c1);
-	} else {
+	if (c0 == c1) {
 		return;
 	}
 
@@ -347,7 +258,7 @@ static struct ast_frame *native_rtp_framehook(struct ast_channel *chan, struct a
 
 	if (bridge) {
 		if (f->subclass.integer == AST_CONTROL_HOLD) {
-			native_rtp_bridge_stop(bridge, chan, NULL);
+			native_rtp_bridge_stop(bridge, chan);
 		} else if ((f->subclass.integer == AST_CONTROL_UNHOLD) || (f->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER)) {
 			native_rtp_bridge_start(bridge, chan);
 		}
@@ -511,9 +422,33 @@ static void native_rtp_bridge_unsuspend(struct ast_bridge *bridge, struct ast_br
 
 static void native_rtp_bridge_leave(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 {
+	struct ast_rtp_glue *glue;
+	RAII_VAR(struct ast_rtp_instance *, instance, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_rtp_instance *, vinstance, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_rtp_instance *, tinstance, NULL, ao2_cleanup);
+
 	native_rtp_bridge_framehook_detach(bridge_channel);
 
-	native_rtp_bridge_stop(bridge, NULL, bridge_channel);
+	glue = ast_rtp_instance_get_glue(ast_channel_tech(bridge_channel->chan)->type);
+	glue->get_rtp_info(bridge_channel->chan, &instance);
+	glue->get_vrtp_info ? glue->get_vrtp_info(bridge_channel->chan, &vinstance) : AST_RTP_GLUE_RESULT_FORBID;
+	glue->get_trtp_info ? glue->get_trtp_info(bridge_channel->chan, &tinstance) : AST_RTP_GLUE_RESULT_FORBID;
+
+	/* Tear down P2P bridges */
+	if (instance) {
+		ast_rtp_instance_set_bridged(instance, NULL);
+	}
+	if (vinstance) {
+		ast_rtp_instance_set_bridged(vinstance, NULL);
+	}
+	if (tinstance) {
+		ast_rtp_instance_set_bridged(tinstance, NULL);
+	}
+
+	/* Direct RTP may have occurred, tear it down */
+	glue->update_peer(bridge_channel->chan, NULL, NULL, NULL, NULL, 0);
+
+	native_rtp_bridge_stop(bridge, NULL);
 }
 
 static int native_rtp_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)