[Asterisk-code-review] chan pjsip: fix switching sending codec when asymmetric rtp ... (asterisk[13])

Anonymous Coward asteriskteam at digium.com
Wed Nov 30 10:48:13 CST 2016


Anonymous Coward #1000019 has submitted this change and it was merged. ( https://gerrit.asterisk.org/4453 )

Change subject: chan_pjsip: fix switching sending codec when asymmetric_rtp_codec=no
......................................................................


chan_pjsip: fix switching sending codec when asymmetric_rtp_codec=no

The sending codec is switched to the receiving codec and then
is switched back to the best native codec on EVERY receiving RTP packets.
This is because after call of ast_channel_set_rawwriteformat there is call
of ast_set_write_format which calls set_format which sets rawwriteformat
to the best native format.

This patch adds a new function ast_set_write_format_path which set
specific write path on channel and uses this function to switch
the sending codec.

ASTERISK-26603 #close

Change-Id: I5b7d098f8b254ce8f45546e6c36e5d324737f71d
---
M channels/chan_pjsip.c
M include/asterisk/channel.h
M main/channel.c
3 files changed, 57 insertions(+), 3 deletions(-)

Approvals:
  George Joseph: Looks good to me, approved
  Daniel Heckl: Looks good to me, but someone else must approve
  Anonymous Coward #1000019: Verified
  Joshua Colp: Looks good to me, but someone else must approve



diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index cc4b2ef..6e3d087 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -679,7 +679,11 @@
 	return f;
 }
 
-/*! \brief Function called by core to read any waiting frames */
+/*!
+ * \brief Function called by core to read any waiting frames 
+ *
+ * \note The channel is already locked.
+ */
 static struct ast_frame *chan_pjsip_read(struct ast_channel *ast)
 {
 	struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
@@ -737,8 +741,7 @@
 		ast_debug(1, "Oooh, got a frame with format of %s on channel '%s' when we're sending '%s', switching to match\n",
 			ast_format_get_name(f->subclass.format), ast_channel_name(ast),
 			ast_format_get_name(ast_channel_rawwriteformat(ast)));
-		ast_channel_set_rawwriteformat(ast, f->subclass.format);
-		ast_set_write_format(ast, ast_channel_writeformat(ast));
+		ast_set_write_format_path(ast, ast_channel_writeformat(ast), f->subclass.format);
 
 		if (ast_channel_is_bridged(ast)) {
 			ast_channel_set_unbridged_nolock(ast, 1);
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index a76e606..0735119 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -2003,6 +2003,21 @@
 int ast_set_read_format_path(struct ast_channel *chan, struct ast_format *raw_format, struct ast_format *core_format);
 
 /*!
+ * \brief Set specific write path on channel.
+ * \since 13.13.0
+ *
+ * \param chan Channel to setup write path.
+ * \param core_format What the core wants to write.
+ * \param raw_format Raw write format.
+ *
+ * \pre chan is locked
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int ast_set_write_format_path(struct ast_channel *chan, struct ast_format *core_format, struct ast_format *raw_format);
+
+/*!
  * \brief Sets read format on channel chan from capabilities
  * Set read format for channel to whichever component of "format" is best.
  * \param chan channel to change
diff --git a/main/channel.c b/main/channel.c
index 278104c..357eb31 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -5447,6 +5447,42 @@
 	return 0;
 }
 
+int ast_set_write_format_path(struct ast_channel *chan, struct ast_format *core_format, struct ast_format *raw_format)
+{
+	struct ast_trans_pvt *trans_old;
+	struct ast_trans_pvt *trans_new;
+
+	if (ast_format_cmp(ast_channel_rawwriteformat(chan), raw_format) == AST_FORMAT_CMP_EQUAL
+		&& ast_format_cmp(ast_channel_writeformat(chan), core_format) == AST_FORMAT_CMP_EQUAL) {
+		/* Nothing to setup */
+		return 0;
+	}
+
+	ast_debug(1, "Channel %s setting write format path: %s -> %s\n",
+		ast_channel_name(chan),
+		ast_format_get_name(core_format),
+		ast_format_get_name(raw_format));
+
+	/* Setup new translation path. */
+	if (ast_format_cmp(raw_format, core_format) != AST_FORMAT_CMP_EQUAL) {
+		trans_new = ast_translator_build_path(raw_format, core_format);
+		if (!trans_new) {
+			return -1;
+		}
+	} else {
+		/* No translation needed. */
+		trans_new = NULL;
+	}
+	trans_old = ast_channel_writetrans(chan);
+	if (trans_old) {
+		ast_translator_free_path(trans_old);
+	}
+	ast_channel_writetrans_set(chan, trans_new);
+	ast_channel_set_rawwriteformat(chan, raw_format);
+	ast_channel_set_writeformat(chan, core_format);
+	return 0;
+}
+
 struct set_format_access {
 	const char *direction;
 	struct ast_trans_pvt *(*get_trans)(const struct ast_channel *chan);

-- 
To view, visit https://gerrit.asterisk.org/4453
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I5b7d098f8b254ce8f45546e6c36e5d324737f71d
Gerrit-PatchSet: 3
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Owner: Alexei Gradinari <alex2grad at gmail.com>
Gerrit-Reviewer: Alexei Gradinari <alex2grad at gmail.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Daniel Heckl <daniel.heckl at gmail.com>
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>



More information about the asterisk-code-review mailing list