[asterisk-commits] oej: branch group/pinefool-poor-mans-plc-1.4 r383908 - in /team/group/pinefoo...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Mar 26 07:33:35 CDT 2013
Author: oej
Date: Tue Mar 26 07:33:30 2013
New Revision: 383908
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383908
Log:
Various updates to handle weird situations.
Again, thanks to Martin at VoipMonitor.org for a brainstorm session.
Modified:
team/group/pinefool-poor-mans-plc-1.4/README.pinefool-poor-mans-plc
team/group/pinefool-poor-mans-plc-1.4/channels/chan_sip.c
team/group/pinefool-poor-mans-plc-1.4/configs/rtp.conf.sample
team/group/pinefool-poor-mans-plc-1.4/main/rtp.c
Modified: team/group/pinefool-poor-mans-plc-1.4/README.pinefool-poor-mans-plc
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefool-poor-mans-plc-1.4/README.pinefool-poor-mans-plc?view=diff&rev=383908&r1=383907&r2=383908
==============================================================================
--- team/group/pinefool-poor-mans-plc-1.4/README.pinefool-poor-mans-plc (original)
+++ team/group/pinefool-poor-mans-plc-1.4/README.pinefool-poor-mans-plc Tue Mar 26 07:33:30 2013
@@ -83,6 +83,7 @@
- http://en.wikipedia.org/wiki/Packet_loss_concealment
- http://research.microsoft.com/pubs/73282/network-survey-1998.pdf
- http://ivms.stanford.edu/~liang/research/sigproc2/
+- http://www.ietf.org/rfc/rfc3550.txt - The RTP RFC
And finally a description of the current PLC in Asterisk
- https://wiki.asterisk.org/wiki/display/AST/Packet+Loss+Concealment+%28PLC%29
Modified: team/group/pinefool-poor-mans-plc-1.4/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefool-poor-mans-plc-1.4/channels/chan_sip.c?view=diff&rev=383908&r1=383907&r2=383908
==============================================================================
--- team/group/pinefool-poor-mans-plc-1.4/channels/chan_sip.c (original)
+++ team/group/pinefool-poor-mans-plc-1.4/channels/chan_sip.c Tue Mar 26 07:33:30 2013
@@ -4901,7 +4901,9 @@
free(p);
return NULL;
}
- ast_rtp_set_plc(p->rtp, ast_test_flag(&p->flags[1], SIP_DTMF) == SIP_PAGE2_POORMANSPLC);
+ if (ast_test_flag(&p->flags[1], SIP_PAGE2_POORMANSPLC)) {
+ ast_rtp_set_plc(p->rtp, TRUE);
+ }
ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
ast_rtp_settos(p->rtp, global_tos_audio);
@@ -10767,6 +10769,9 @@
if (p->rtp) {
ast_rtp_codec_setpref(p->rtp, &p->prefs);
p->autoframing = user->autoframing;
+ if (ast_test_flag(&p->flags[1], SIP_PAGE2_POORMANSPLC)) {
+ ast_rtp_set_plc(p->rtp, TRUE);
+ }
}
/* replace callerid if rpid found, and not restricted */
if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
@@ -10786,6 +10791,9 @@
ast_log(LOG_WARNING, "Unable to cancel SIP destruction. Expect bad things.\n");
ast_copy_flags(&p->flags[0], &user->flags[0], SIP_FLAGS_TO_COPY);
ast_copy_flags(&p->flags[1], &user->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
+ if (ast_test_flag(&p->flags[1], SIP_PAGE2_POORMANSPLC)) {
+ ast_rtp_set_plc(p->rtp, TRUE);
+ }
/* Copy SIP extensions profile from INVITE */
if (p->sipoptions)
user->sipoptions = p->sipoptions;
@@ -10867,6 +10875,9 @@
if (p->rtp) {
ast_rtp_codec_setpref(p->rtp, &peer->prefs);
p->autoframing = peer->autoframing;
+ if (ast_test_flag(&p->flags[1], SIP_PAGE2_POORMANSPLC)) {
+ ast_rtp_set_plc(p->rtp, TRUE);
+ }
}
if (debug)
ast_verbose("Found peer '%s'\n", peer->name);
@@ -10912,6 +10923,10 @@
ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
ast_string_field_set(p, peername, peer->name);
ast_string_field_set(p, authname, peer->name);
+
+ if (p->rtp && ast_test_flag(&p->flags[1], SIP_PAGE2_POORMANSPLC)) {
+ ast_rtp_set_plc(p->rtp, TRUE);
+ }
if (sipmethod == SIP_INVITE) {
/* destroy old channel vars and copy new channel vars */
Modified: team/group/pinefool-poor-mans-plc-1.4/configs/rtp.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefool-poor-mans-plc-1.4/configs/rtp.conf.sample?view=diff&rev=383908&r1=383907&r2=383908
==============================================================================
--- team/group/pinefool-poor-mans-plc-1.4/configs/rtp.conf.sample (original)
+++ team/group/pinefool-poor-mans-plc-1.4/configs/rtp.conf.sample Tue Mar 26 07:33:30 2013
@@ -27,3 +27,12 @@
; be a gap in the outbound sequence numbers as well, which in most cases will help
; both codecs and jitter buffers/PLC functions in the receiving end - a phone or a gateway.
donthidepacketloss = no
+
+; If a channel driver turns on Poor Man's PLC the RTP channel will replace lost packets
+; with a copy of a previous packet. The "plcmax" setting defines the maximum number of
+; packets inserted in one operation. If the seqno indicates 200 lost packets, it doesn't
+; make much sense to inject all of them. (default 10)
+; For many codecs, the size of the packet is 20 ms (see packetization settings)
+; so 10 packets is 0.2 secs of noise. 50 packets is a second and will sound really bad.
+;plcmax = 42
+
Modified: team/group/pinefool-poor-mans-plc-1.4/main/rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinefool-poor-mans-plc-1.4/main/rtp.c?view=diff&rev=383908&r1=383907&r2=383908
==============================================================================
--- team/group/pinefool-poor-mans-plc-1.4/main/rtp.c (original)
+++ team/group/pinefool-poor-mans-plc-1.4/main/rtp.c Tue Mar 26 07:33:30 2013
@@ -77,8 +77,11 @@
static int dtmftimeout = DEFAULT_DTMF_TIMEOUT;
-static int poormansplc; /*!< Are we using poor man's packet loss concealment? */
+
static int donthidepacketloss; /*!< Do not hide packet loss on outbound RTP - default off */
+static int plcmax; /*!< Maximum number of PLC injections in the stream in one operation */
+#define DEFAULT_PLCMAX 10
+
static int rtpstart; /*!< First port for RTP sessions (set in rtp.conf) */
static int rtpend; /*!< Last port for RTP sessions (set in rtp.conf) */
static int rtpdebug; /*!< Are we debugging? */
@@ -580,6 +583,9 @@
{
if (state) {
ast_set_flag(rtp, FLAG_POORMANSPLC);
+ if (option_debug > 2) {
+ ast_log(LOG_DEBUG, "*** Enabling PLC for this call\n");
+ }
} else {
ast_clear_flag(rtp, FLAG_POORMANSPLC);
}
@@ -1356,30 +1362,64 @@
rtp->cycles += RTP_SEQ_MOD;
if (rtp->rxcount > 1) {
- if (ast_test_flag(rtp, FLAG_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;
- }
+ int MAX_MISORDER = 100;
+ int not_jitter = 0;
+
+ /* RTP sequence numbers are consecutive. Have we lost a packet? */
lostpackets = (int) seqno - (int) rtp->lastrxseqno - 1;
- /* RTP sequence numbers are consecutive. Have we lost a packet? */
- if (lostpackets && option_debug > 2) {
- ast_log(LOG_DEBUG, "**** Packet loss detected - # %d. Current Seqno %-6.6u\n", lostpackets, seqno);
- }
- if (ast_test_flag(rtp, FLAG_POORMANSPLC) && rtp->plcbuf != NULL) {
- int i;
- rtp->lastrxseqno++;
- /* Fix the seqno in the frame */
- rtp->plcbuf->seqno = rtp->lastrxseqno;
- /* OEJ:: Fix timestamp */
- ;rtp->lastrxts = timestamp;
- 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);
+ if (lostpackets > MAX_MISORDER) {
+ /* We have a new seqno sequence and will just have to live with it */
+ lostpackets = 0;
+ }
+ if (seqno < rtp->lastrxseqno && (rtp->lastrxseqno - seqno) > MAX_MISORDER) {
+ /* We have a new seqno that is much lower than the previous one. */
+ /* The difference is bigger than normal jitter, so assume a new
+ seqno series */
+ lostpackets = 0;
+ not_jitter = 1;
+ }
+
+ if (!mark) {
+ /* If we have a marker bit set, the SSRC and the SEQNO have changed and
+ we can't compare with the previous one. Just go ahead and wait for
+ the next packet
+ */
+ if (ast_test_flag(rtp, FLAG_POORMANSPLC) && seqno < rtp->lastrxseqno && not_jitter == 0) {
+ /* This is a latecomer that 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.
+ */
+ if (rtp_debug_test_addr(&sin)) {
+ ast_verbose("Ignoring RTP from %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u) - jitter?\n",
+ ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen);
+ }
+ return AST_LIST_FIRST(&frames) ? AST_LIST_FIRST(&frames) : &ast_null_frame;
+ }
+ }
+
+ if (lostpackets) {
+ if(option_debug > 2) {
+ ast_log(LOG_DEBUG, "**** Packet loss detected - # %d. Current Seqno %-6.6u\n", lostpackets, seqno);
+ }
+ if (ast_test_flag(rtp, FLAG_POORMANSPLC) && rtp->plcbuf != NULL) {
+ int i;
+ for (i = 0; i < lostpackets && i < plcmax; i++) {
+ rtp->lastrxseqno++;
+ /* Fix the seqno in the frame */
+ rtp->plcbuf->seqno = rtp->lastrxseqno;
+ rtp->plcbuf->ts += rtp->plcbuf->len;
+
+ AST_LIST_INSERT_TAIL(&frames, ast_frdup(rtp->plcbuf), frame_list);
+ if (option_debug > 2) {
+ ast_log(LOG_DEBUG, "**** Inserting buffer frame %d. \n", i + 1);
+ }
+ }
+ } else {
+ if (ast_test_flag(rtp, FLAG_POORMANSPLC) && option_debug > 2 && rtp->plcbuf == NULL) {
+ ast_log(LOG_DEBUG, " *** Not copying frame from PLCbuf, since it's empty \n");
+ }
}
}
}
@@ -1498,6 +1538,10 @@
ast_frame_free(rtp->plcbuf, 0);
}
rtp->plcbuf = ast_frdup(&rtp->f);
+ } else {
+ if (option_debug > 1 && lostpackets) {
+ ast_log(LOG_DEBUG, " *** Not copying frame into plcbuf PLC=%s\n", ast_test_flag(rtp, FLAG_POORMANSPLC) ? "On" : "Off");
+ }
}
AST_LIST_INSERT_TAIL(&frames, &rtp->f, frame_list);
@@ -2064,11 +2108,9 @@
rtp->us.sin_family = AF_INET;
rtp->ssrc = ast_random();
rtp->seqno = ast_random() & 0xffff;
+ rtp->lastrxseqno = 0;
ast_set_flag(rtp, FLAG_HAS_DTMF);
rtp->plcbuf = NULL;
- if (poormansplc) {
- ast_set_flag(rtp, FLAG_POORMANSPLC);
- }
return;
}
@@ -2861,11 +2903,13 @@
if (donthidepacketloss && rtp->prev_frame_seqno > 0 && f->seqno && f->seqno != (rtp->prev_frame_seqno + 1)) {
/* We have incoming packet loss and need to signal that outbound. */
unsigned int loss = f->seqno - rtp->prev_frame_seqno - 1;
- if (option_debug > 2) {
- ast_log(LOG_DEBUG, "**** Incoming packet loss, letting it through: %u packets\n", loss);
- }
- /* Jump ahead, let the packet loss go straight through */
- rtp->seqno += loss;
+ if (f->seqno > rtp->prev_frame_seqno) {
+ if (option_debug > 2) {
+ ast_log(LOG_DEBUG, "**** Incoming packet loss, letting it through: %u packets\n", loss);
+ }
+ /* Jump ahead, let the packet loss go straight through */
+ rtp->seqno += loss;
+ }
}
ms = calc_txstamp(rtp, &f->delivery);
@@ -4035,8 +4079,8 @@
struct ast_config *cfg;
const char *s;
- poormansplc = 0;
donthidepacketloss = 0;
+ plcmax = DEFAULT_PLCMAX;
rtpstart = 5000;
rtpend = 31000;
dtmftimeout = DEFAULT_DTMF_TIMEOUT;
@@ -4076,10 +4120,16 @@
ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
#endif
}
+ if ((s = ast_variable_retrieve(cfg, "general", "plcmax"))) {
+ plcmax = atoi(s);
+ if (option_debug > 1) {
+ ast_log(LOG_DEBUG, "PLCmax: Maximum number of injected RTP packets in one operation %d\n", plcmax);
+ }
+ }
if ((s = ast_variable_retrieve(cfg, "general", "donthidepacketloss"))) {
donthidepacketloss = ast_true(s);
if (option_debug > 1) {
- ast_log(LOG_DEBUG, "*** Hiding packet loss on outbound RTP stream? %s\n", donthidepacketloss ? "on" : "off" );
+ ast_log(LOG_DEBUG, "Hiding packet loss on outbound RTP stream? %s\n", donthidepacketloss ? "on" : "off" );
}
}
if ((s = ast_variable_retrieve(cfg, "general", "dtmftimeout"))) {
More information about the asterisk-commits
mailing list