[asterisk-commits] oej: branch oej/pinefool-poor-mans-plc-1.8 r383453 - in /team/oej/pinefool-po...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Mar 20 14:50:06 CDT 2013


Author: oej
Date: Wed Mar 20 14:50:02 2013
New Revision: 383453

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383453
Log:
Say hello to my poor man

Modified:
    team/oej/pinefool-poor-mans-plc-1.8/configs/rtp.conf.sample
    team/oej/pinefool-poor-mans-plc-1.8/res/res_rtp_asterisk.c

Modified: team/oej/pinefool-poor-mans-plc-1.8/configs/rtp.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinefool-poor-mans-plc-1.8/configs/rtp.conf.sample?view=diff&rev=383453&r1=383452&r2=383453
==============================================================================
--- team/oej/pinefool-poor-mans-plc-1.8/configs/rtp.conf.sample (original)
+++ team/oej/pinefool-poor-mans-plc-1.8/configs/rtp.conf.sample Wed Mar 20 14:50:02 2013
@@ -32,3 +32,16 @@
 ; if rtp packets are dropped from one or both ends after a call is
 ; connected. This option is set to 4 by default.
 ; probation=8
+
+; The RTP channels has an implementation of Packet Loss Concealment
+; that is named "Poor Man's PLC". Normally a PLC happens withing the
+; context of a jitter buffer. This PLC just copies the previous
+; packet into the stream again if a packet (or multiple) is missing.
+; If a packet arrives too late (reordered) it will be ignored.
+; This introduces a bit of jitter since we're sending two
+; packets at the same time. Hopefully the phone or gw at the
+; end of the line will have a jitter buffer and play out the media
+; properly. This PLC will make sure that Asterisk outbound RTP streams has
+; less skew and that recordings will actually have a proper amount of
+; media. Default is turned off.
+;plc=yes

Modified: team/oej/pinefool-poor-mans-plc-1.8/res/res_rtp_asterisk.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinefool-poor-mans-plc-1.8/res/res_rtp_asterisk.c?view=diff&rev=383453&r1=383452&r2=383453
==============================================================================
--- team/oej/pinefool-poor-mans-plc-1.8/res/res_rtp_asterisk.c (original)
+++ team/oej/pinefool-poor-mans-plc-1.8/res/res_rtp_asterisk.c Wed Mar 20 14:50:02 2013
@@ -87,6 +87,7 @@
 
 static int rtpstart = DEFAULT_RTP_START;			/*!< First port for RTP sessions (set in rtp.conf) */
 static int rtpend = DEFAULT_RTP_END;			/*!< Last port for RTP sessions (set in rtp.conf) */
+static int poormansplc;                 /*!< Are we using poor man's packet loss concealment? */
 static int rtpdebug;			/*!< Are we debugging? */
 static int rtcpdebug;			/*!< Are we debugging RTCP? */
 static int rtcpstats;			/*!< Are we debugging RTCP? */
@@ -118,6 +119,7 @@
 struct ast_rtp {
 	int s;
 	struct ast_frame f;
+	struct ast_frame *plcbuf;	/*!< Buffer for Poor man's PLC */
 	unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
 	unsigned int ssrc;		/*!< Synchronization source, RFC 3550, page 10. */
 	unsigned int themssrc;		/*!< Their SSRC */
@@ -529,6 +531,7 @@
 	}
 
 	/* Set default parameters on the newly created RTP structure */
+	rtp->plcbuf = NULL;
 	rtp->ssrc = ast_random();
 	rtp->seqno = ast_random() & 0xffff;
 	rtp->strict_rtp_state = (strictrtp ? STRICT_RTP_LEARN : STRICT_RTP_OPEN);
@@ -612,6 +615,9 @@
 	if (rtp->red) {
 		AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
 		ast_free(rtp->red);
+	}
+	if (rtp->plcbuf != NULL) {
+		ast_frfree(rtp->plcbuf);
 	}
 
 	/* Finally destroy ourselves */
@@ -2126,6 +2132,7 @@
 	struct ast_rtp_payload_type payload;
 	struct ast_sockaddr remote_address = { {0,} };
 	struct frame_list frames;
+	int lostpackets = 0;
 
 	/* If this is actually RTCP let's hop on over and handle it */
 	if (rtcp) {
@@ -2326,6 +2333,30 @@
 	}
 	if ((int)rtp->lastrxseqno - (int)seqno  > 100) /* if so it would indicate that the sender cycled; allow for misordering */
 		rtp->cycles += RTP_SEQ_MOD;
+
+	if (rtp->rxcount > 1) {
+		if (poormansplc && seqno < rtp->lastrxseqno)  {
+			/* This is a latecome we've already replaced. A jitter buffer would have handled this
+			   properly, but in many cases we can't afford a jitterbuffer and will have to live
+			   with the face that the poor man's PLC already has replaced this frame and we can't
+			   insert it AGAIN, because that would cause negative skew.
+			   Henry, just ignore this late visitor. Thank you.
+			*/
+			return AST_LIST_FIRST(&frames) ? AST_LIST_FIRST(&frames) : &ast_null_frame;
+		}
+		lostpackets = (int) seqno - (int) rtp->lastrxseqno - 1;
+		/* RTP sequence numbers are consecutive. Have we lost a packet? */
+		if (lostpackets) {
+			ast_log(LOG_DEBUG, "**** Packet loss detected - # %d. Current Seqno %-6.6u\n", lostpackets, seqno);
+		}
+		if (poormansplc && rtp->plcbuf != NULL) {
+			int i;
+			for (i = 0; i < lostpackets; i++) {
+				AST_LIST_INSERT_TAIL(&frames, ast_frdup(rtp->plcbuf), frame_list);
+				ast_log(LOG_DEBUG, "**** Inserting buffer frame %d. \n", i + 1);
+			}
+		}
+	}
 
 	prev_seqno = rtp->lastrxseqno;
 	rtp->lastrxseqno = seqno;
@@ -2493,6 +2524,18 @@
 		rtp->f.delivery.tv_usec = 0;
 	}
 
+	//	if (rtp->plcbuf) {
+	//		ast_frfree(rtp->plcbuf);
+	//	}
+	if (poormansplc) {
+		/* Copy this frame to buffer */
+		if (rtp->plcbuf) {
+			/* We have something here. Take it away, dear Henry. */
+			ast_frame_free(rtp->plcbuf, 0);
+		}
+		rtp->plcbuf = ast_frdup(&rtp->f);
+	}
+
 	AST_LIST_INSERT_TAIL(&frames, &rtp->f, frame_list);
 	return AST_LIST_FIRST(&frames);
 }
@@ -2978,6 +3021,7 @@
 	rtpend = DEFAULT_RTP_END;
 	dtmftimeout = DEFAULT_DTMF_TIMEOUT;
 	strictrtp = STRICT_RTP_OPEN;
+	poormansplc = 0;
 	learning_min_sequential = DEFAULT_LEARNING_MIN_SEQUENTIAL;
 	if (cfg) {
 		if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
@@ -3011,6 +3055,12 @@
 				ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
 #endif
 		}
+		if ((s = ast_variable_retrieve(cfg, "general", "plc"))) {
+			poormansplc = ast_true(s);
+			if (option_debug > 1) {
+				ast_log(LOG_DEBUG, "*** Poor man's PLC is turned %s\n", poormansplc ? "on" : "off" );
+			}
+		}
 		if ((s = ast_variable_retrieve(cfg, "general", "dtmftimeout"))) {
 			dtmftimeout = atoi(s);
 			if ((dtmftimeout < 0) || (dtmftimeout > 64000)) {




More information about the asterisk-commits mailing list