[asterisk-commits] format: Reintroduce smoother flags (asterisk[master])

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jun 6 08:59:38 CDT 2017


Jenkins2 has submitted this change and it was merged. ( https://gerrit.asterisk.org/5731 )

Change subject: format: Reintroduce smoother flags
......................................................................


format: Reintroduce smoother flags

In review 4843 (ASTERISK-24858), we added a hack that forced a smoother
creation when sending signed linear so that the byte order was adjusted
during transmission. This was needed because smoother flags were lost
during the new format work that was done in Asterisk 13.

Rather than rolling that same hack into res_rtp_multicast, re-introduce
smoother flags so that formats can dictate their own options.

Change-Id: I77b835fba0e539c6ce50014a984766f63cab2c16
---
M include/asterisk/codec.h
M include/asterisk/format.h
M include/asterisk/smoother.h
M main/codec_builtin.c
M main/format.c
M res/res_rtp_asterisk.c
M res/res_rtp_multicast.c
7 files changed, 130 insertions(+), 49 deletions(-)

Approvals:
  Kevin Harwell: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved
  Jenkins2: Approved for Submit
  Joshua Colp: Looks good to me, but someone else must approve



diff --git a/include/asterisk/codec.h b/include/asterisk/codec.h
index 2f5756c..79798ac 100644
--- a/include/asterisk/codec.h
+++ b/include/asterisk/codec.h
@@ -76,6 +76,8 @@
 	int (*get_length)(unsigned int samples);
 	/*! \brief Whether the media can be smoothed or not */
 	unsigned int smooth;
+	/*! \brief Flags to be passed to the smoother */
+	unsigned int smoother_flags;
 	/*! \brief The module that registered this codec */
 	struct ast_module *mod;
 };
diff --git a/include/asterisk/format.h b/include/asterisk/format.h
index b01592d..0bad96d 100644
--- a/include/asterisk/format.h
+++ b/include/asterisk/format.h
@@ -356,6 +356,17 @@
 int ast_format_can_be_smoothed(const struct ast_format *format);
 
 /*!
+ * \since 13.17.0
+ *
+ * \brief Get smoother flags for this format
+ *
+ * \param format The media format
+ *
+ * \return smoother flags for the provided format
+ */
+int ast_format_get_smoother_flags(const struct ast_format *format);
+
+/*!
  * \brief Get the media type of a format
  *
  * \param format The media format
diff --git a/include/asterisk/smoother.h b/include/asterisk/smoother.h
index e63aa77..65ac889 100644
--- a/include/asterisk/smoother.h
+++ b/include/asterisk/smoother.h
@@ -33,6 +33,7 @@
 
 #define AST_SMOOTHER_FLAG_G729		(1 << 0)
 #define AST_SMOOTHER_FLAG_BE		(1 << 1)
+#define AST_SMOOTHER_FLAG_FORCED	(1 << 2)
 
 /*! \name AST_Smoother
 */
diff --git a/main/codec_builtin.c b/main/codec_builtin.c
index 3320900..32ec12d 100644
--- a/main/codec_builtin.c
+++ b/main/codec_builtin.c
@@ -36,6 +36,7 @@
 #include "asterisk/format.h"
 #include "asterisk/format_cache.h"
 #include "asterisk/frame.h"
+#include "asterisk/smoother.h"
 
 int __ast_codec_register_with_format(struct ast_codec *codec, const char *format_name,
 	struct ast_module *mod);
@@ -288,6 +289,7 @@
 	.samples_count = slin_samples,
 	.get_length = slin_length,
 	.smooth = 1,
+	.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
 };
 
 static struct ast_codec slin12 = {
@@ -302,6 +304,7 @@
 	.samples_count = slin_samples,
 	.get_length = slin_length,
 	.smooth = 1,
+	.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
 };
 
 static struct ast_codec slin16 = {
@@ -316,6 +319,7 @@
 	.samples_count = slin_samples,
 	.get_length = slin_length,
 	.smooth = 1,
+	.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
 };
 
 static struct ast_codec slin24 = {
@@ -330,6 +334,7 @@
 	.samples_count = slin_samples,
 	.get_length = slin_length,
 	.smooth = 1,
+	.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
 };
 
 static struct ast_codec slin32 = {
@@ -344,6 +349,7 @@
 	.samples_count = slin_samples,
 	.get_length = slin_length,
 	.smooth = 1,
+	.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
 };
 
 static struct ast_codec slin44 = {
@@ -358,6 +364,7 @@
 	.samples_count = slin_samples,
 	.get_length = slin_length,
 	.smooth = 1,
+	.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
 };
 
 static struct ast_codec slin48 = {
@@ -372,6 +379,7 @@
 	.samples_count = slin_samples,
 	.get_length = slin_length,
 	.smooth = 1,
+	.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
 };
 
 static struct ast_codec slin96 = {
@@ -386,6 +394,7 @@
 	.samples_count = slin_samples,
 	.get_length = slin_length,
 	.smooth = 1,
+	.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
 };
 
 static struct ast_codec slin192 = {
@@ -400,6 +409,7 @@
 	.samples_count = slin_samples,
 	.get_length = slin_length,
 	.smooth = 1,
+	.smoother_flags = AST_SMOOTHER_FLAG_BE | AST_SMOOTHER_FLAG_FORCED,
 };
 
 static int lpc10_samples(struct ast_frame *frame)
diff --git a/main/format.c b/main/format.c
index 5ae5ad9..09e736c 100644
--- a/main/format.c
+++ b/main/format.c
@@ -391,6 +391,11 @@
 	return format->codec->smooth;
 }
 
+int ast_format_get_smoother_flags(const struct ast_format *format)
+{
+	return format->codec->smoother_flags;
+}
+
 enum ast_media_type ast_format_get_type(const struct ast_format *format)
 {
 	return format->codec->type;
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index 18987ce..c120fc1 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -3747,7 +3747,7 @@
 }
 
 /*! \pre instance is locked */
-static int ast_rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame *frame, int codec)
+static int rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame *frame, int codec)
 {
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 	int pred, mark = 0;
@@ -4016,10 +4016,10 @@
 
 	/* If no smoother is present see if we have to set one up */
 	if (!rtp->smoother && ast_format_can_be_smoothed(format)) {
+		unsigned int smoother_flags = ast_format_get_smoother_flags(format);
 		unsigned int framing_ms = ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(instance));
-		int is_slinear = ast_format_cache_is_slinear(format);
 
-		if (!framing_ms && is_slinear) {
+		if (!framing_ms && (smoother_flags & AST_SMOOTHER_FLAG_FORCED)) {
 			framing_ms = ast_format_get_default_ms(format);
 		}
 
@@ -4030,9 +4030,7 @@
 					ast_format_get_name(format), framing_ms, ast_format_get_minimum_bytes(format));
 				return -1;
 			}
-			if (is_slinear) {
-				ast_smoother_set_flags(rtp->smoother, AST_SMOOTHER_FLAG_BE);
-			}
+			ast_smoother_set_flags(rtp->smoother, smoother_flags);
 		}
 	}
 
@@ -4047,7 +4045,7 @@
 		}
 
 		while ((f = ast_smoother_read(rtp->smoother)) && (f->data.ptr)) {
-				ast_rtp_raw_write(instance, f, codec);
+				rtp_raw_write(instance, f, codec);
 		}
 	} else {
 		int hdrlen = 12;
@@ -4059,7 +4057,7 @@
 			f = frame;
 		}
 		if (f->data.ptr) {
-			ast_rtp_raw_write(instance, f, codec);
+			rtp_raw_write(instance, f, codec);
 		}
 		if (f != frame) {
 			ast_frfree(f);
diff --git a/res/res_rtp_multicast.c b/res/res_rtp_multicast.c
index 42de11f..14176da 100644
--- a/res/res_rtp_multicast.c
+++ b/res/res_rtp_multicast.c
@@ -54,6 +54,7 @@
 #include "asterisk/format_cache.h"
 #include "asterisk/multicast_rtp.h"
 #include "asterisk/app.h"
+#include "asterisk/smoother.h"
 
 /*! Command value used for Linksys paging to indicate we are starting */
 #define LINKSYS_MCAST_STARTCMD 6
@@ -95,6 +96,7 @@
 	uint16_t seqno;
 	unsigned int lastts;	
 	struct timeval txcore;
+	struct ast_smoother *smoother;
 };
 
 enum {
@@ -395,9 +397,53 @@
 		multicast_send_control_packet(instance, multicast, LINKSYS_MCAST_STOPCMD);
 	}
 
+	if (multicast->smoother) {
+		ast_smoother_free(multicast->smoother);
+	}
+
 	close(multicast->socket);
 
 	ast_free(multicast);
+
+	return 0;
+}
+
+static int rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame *frame, int codec)
+{
+	struct multicast_rtp *multicast = ast_rtp_instance_get_data(instance);
+	unsigned int ms = calc_txstamp(multicast, &frame->delivery);
+	unsigned char *rtpheader;
+	struct ast_sockaddr remote_address = { {0,} };
+	int rate = rtp_get_rate(frame->subclass.format) / 1000;
+	int hdrlen = 12;
+
+	/* Calculate last TS */
+	multicast->lastts = multicast->lastts + ms * rate;
+
+	/* Construct an RTP header for our packet */
+	rtpheader = (unsigned char *)(frame->data.ptr - hdrlen);
+	put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (multicast->seqno)));
+
+	if (ast_test_flag(frame, AST_FRFLAG_HAS_TIMING_INFO)) {
+		put_unaligned_uint32(rtpheader + 4, htonl(frame->ts * 8));
+	} else {
+		put_unaligned_uint32(rtpheader + 4, htonl(multicast->lastts));
+	}
+
+	put_unaligned_uint32(rtpheader + 8, htonl(multicast->ssrc));
+
+	/* Increment sequence number and wrap to 0 if it overflows 16 bits. */
+	multicast->seqno = 0xFFFF & (multicast->seqno + 1);
+
+	/* Finally send it out to the eager phones listening for us */
+	ast_rtp_instance_get_remote_address(instance, &remote_address);
+
+	if (ast_sendto(multicast->socket, (void *) rtpheader, frame->datalen + hdrlen, 0, &remote_address) < 0) {
+		ast_log(LOG_ERROR, "Multicast RTP Transmission error to %s: %s\n",
+			ast_sockaddr_stringify(&remote_address),
+			strerror(errno));
+		return -1;
+	}
 
 	return 0;
 }
@@ -406,12 +452,9 @@
 static int multicast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
 {
 	struct multicast_rtp *multicast = ast_rtp_instance_get_data(instance);
-	struct ast_frame *f = frame;
-	struct ast_sockaddr remote_address;
-	int hdrlen = 12, res = 0, codec;
-	unsigned char *rtpheader;
-	unsigned int ms = calc_txstamp(multicast, &frame->delivery);
-	int rate = rtp_get_rate(frame->subclass.format) / 1000;
+	struct ast_format *format;
+	struct ast_frame *f;
+	int codec;
 
 	/* We only accept audio, nothing else */
 	if (frame->frametype != AST_FRAME_VOICE) {
@@ -425,45 +468,56 @@
 		return -1;
 	}
 
-	/* If we do not have space to construct an RTP header duplicate the frame so we get some */
-	if (frame->offset < hdrlen) {
-		f = ast_frdup(frame);
+	format = frame->subclass.format;
+	if (!multicast->smoother && ast_format_can_be_smoothed(format)) {
+		unsigned int smoother_flags = ast_format_get_smoother_flags(format);
+		unsigned int framing_ms = ast_rtp_codecs_get_framing(ast_rtp_instance_get_codecs(instance));
+
+		if (!framing_ms && (smoother_flags & AST_SMOOTHER_FLAG_FORCED)) {
+			framing_ms = ast_format_get_default_ms(format);
+		}
+
+		if (framing_ms) {
+			multicast->smoother = ast_smoother_new((framing_ms * ast_format_get_minimum_bytes(format)) / ast_format_get_minimum_ms(format));
+			if (!multicast->smoother) {
+				ast_log(LOG_WARNING, "Unable to create smoother: format %s ms: %u len %u\n",
+						ast_format_get_name(format), framing_ms, ast_format_get_minimum_bytes(format));
+				return -1;
+			}
+			ast_smoother_set_flags(multicast->smoother, smoother_flags);
+		}
 	}
-	
-	/* Calucate last TS */
-	multicast->lastts = multicast->lastts + ms * rate;
-	
-	/* Construct an RTP header for our packet */
-	rtpheader = (unsigned char *)(f->data.ptr - hdrlen);
-	put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (multicast->seqno)));
-	
-	if (ast_test_flag(f, AST_FRFLAG_HAS_TIMING_INFO)) {
-		put_unaligned_uint32(rtpheader + 4, htonl(f->ts * 8));
+
+	if (multicast->smoother) {
+		if (ast_smoother_test_flag(multicast->smoother, AST_SMOOTHER_FLAG_BE)) {
+			ast_smoother_feed_be(multicast->smoother, frame);
+		} else {
+			ast_smoother_feed(multicast->smoother, frame);
+		}
+
+		while ((f = ast_smoother_read(multicast->smoother)) && f->data.ptr) {
+			rtp_raw_write(instance, f, codec);
+		}
 	} else {
-		put_unaligned_uint32(rtpheader + 4, htonl(multicast->lastts));
+		int hdrlen = 12;
+
+		/* If we do not have space to construct an RTP header duplicate the frame so we get some */
+		if (frame->offset < hdrlen) {
+			f = ast_frdup(frame);
+		} else {
+			f = frame;
+		}
+
+		if (f->data.ptr) {
+			rtp_raw_write(instance, f, codec);
+		}
+
+		if (f != frame) {
+			ast_frfree(f);
+		}
 	}
 
-	put_unaligned_uint32(rtpheader + 8, htonl(multicast->ssrc));
-
-	/* Increment sequence number and wrap to 0 if it overflows 16 bits. */
-	multicast->seqno = 0xFFFF & (multicast->seqno + 1);
-
-	/* Finally send it out to the eager phones listening for us */
-	ast_rtp_instance_get_remote_address(instance, &remote_address);
-
-	if (ast_sendto(multicast->socket, (void *) rtpheader, f->datalen + hdrlen, 0, &remote_address) < 0) {
-		ast_log(LOG_ERROR, "Multicast RTP Transmission error to %s: %s\n",
-			ast_sockaddr_stringify(&remote_address),
-			strerror(errno));
-		res = -1;
-	}
-
-	/* If we were forced to duplicate the frame free the new one */
-	if (frame != f) {
-		ast_frfree(f);
-	}
-
-	return res;
+	return 0;
 }
 
 /*! \brief Function called to read from a multicast instance */

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I77b835fba0e539c6ce50014a984766f63cab2c16
Gerrit-PatchSet: 2
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Sean Bright <sean.bright at gmail.com>
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Jenkins2
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-Reviewer: Sean Bright <sean.bright at gmail.com>



More information about the asterisk-commits mailing list