[asterisk-commits] oej: branch oej/pinetestedition-1.8 r383465 - in /team/oej/pinetestedition-1....
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Mar 20 16:07:25 CDT 2013
Author: oej
Date: Wed Mar 20 16:07:21 2013
New Revision: 383465
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383465
Log:
Adding poor man's PLC to this test branch
Added:
team/oej/pinetestedition-1.8/patches/pinefool-poor-mans-plc-1.8.diff (with props)
Modified:
team/oej/pinetestedition-1.8/channels/chan_sip.c
team/oej/pinetestedition-1.8/channels/sip/include/sip.h
team/oej/pinetestedition-1.8/configs/rtp.conf.sample
team/oej/pinetestedition-1.8/include/asterisk/rtp_engine.h
team/oej/pinetestedition-1.8/main/rtp_engine.c
team/oej/pinetestedition-1.8/res/res_rtp_asterisk.c
Modified: team/oej/pinetestedition-1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinetestedition-1.8/channels/chan_sip.c?view=diff&rev=383465&r1=383464&r2=383465
==============================================================================
--- team/oej/pinetestedition-1.8/channels/chan_sip.c (original)
+++ team/oej/pinetestedition-1.8/channels/chan_sip.c Wed Mar 20 16:07:21 2013
@@ -5672,6 +5672,10 @@
ast_rtp_instance_set_prop(dialog->trtp, AST_RTP_PROPERTY_RTCP, 1);
}
+ if (ast_test_flag(&dialog->flags[2], SIP_PAGE3_POORMANSPLC)) {
+ /* This is only supported for AUDIO */
+ ast_rtp_instance_plc_set_state(dialog->rtp, TRUE);
+ }
ast_rtp_instance_set_timeout(dialog->rtp, dialog->rtptimeout);
ast_rtp_instance_set_hold_timeout(dialog->rtp, dialog->rtpholdtimeout);
@@ -18473,6 +18477,7 @@
ast_cli(fd, " Dynamic : %s\n", AST_CLI_YESNO(peer->host_dynamic));
ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate);
+ ast_cli(fd, " PLC : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[2], SIP_PAGE3_POORMANSPLC)));
ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire));
ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
ast_cli(fd, " Force rport : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)));
@@ -19193,6 +19198,7 @@
ast_cli(a->fd, " Relax DTMF: %s\n", AST_CLI_YESNO(global_relaxdtmf));
ast_cli(a->fd, " RFC2833 Compensation: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE)));
ast_cli(a->fd, " Symmetric RTP: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_SYMMETRICRTP)));
+ ast_cli(a->fd, " Poor man's PLC: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[2], SIP_PAGE3_POORMANSPLC)));
ast_cli(a->fd, " Compact SIP headers: %s\n", AST_CLI_YESNO(sip_cfg.compactheaders));
ast_cli(a->fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
ast_cli(a->fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
@@ -19607,6 +19613,7 @@
ast_cli(a->fd, " Video support %s\n", AST_CLI_YESNO(cur->vrtp != NULL));
ast_cli(a->fd, " Comfort Noise support %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[1],SIP_PAGE2_ALLOW_CN)));
ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate);
+ ast_cli(a->fd, " Poor man's PLC: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[2], SIP_PAGE3_POORMANSPLC)));
ast_cli(a->fd, " Theoretical Address: %s\n", ast_sockaddr_stringify(&cur->sa));
ast_cli(a->fd, " Received Address: %s\n", ast_sockaddr_stringify(&cur->recv));
ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer));
@@ -28057,6 +28064,10 @@
else {
ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
+ }
+ } else if (!strcasecmp(v->name, "plc")) {
+ if (ast_true(v->value)) {
+ ast_set_flag(&flags[2], SIP_PAGE3_POORMANSPLC);
}
} else if (!strcasecmp(v->name, "nat")) {
ast_set_flag(&mask[0], SIP_NAT_FORCE_RPORT);
Modified: team/oej/pinetestedition-1.8/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinetestedition-1.8/channels/sip/include/sip.h?view=diff&rev=383465&r1=383464&r2=383465
==============================================================================
--- team/oej/pinetestedition-1.8/channels/sip/include/sip.h (original)
+++ team/oej/pinetestedition-1.8/channels/sip/include/sip.h Wed Mar 20 16:07:21 2013
@@ -369,9 +369,10 @@
#define SIP_PAGE3_100REL (1 << 3) /*!< D: If PRACK is active for a specific dialog */
#define SIP_PAGE3_INVITE_WAIT_FOR_PRACK (1 << 4) /*!< D: Wait for PRACK response before sending 200 OK */
#define SIP_PAGE3_ANSWER_WAIT_FOR_PRACK (1 << 5) /*!< D: Send ANSWER when PRACK is received */
+#define SIP_PAGE3_POORMANSPLC (1 << 6) /*!< DPG: Enable poor man's PLC - packet loss concealment */
#define SIP_PAGE3_FLAGS_TO_COPY \
- (SIP_PAGE3_SNOM_AOC | SIP_PAGE3_PRACK | SIP_PAGE3_DIRECT_MEDIA_OUTGOING)
+ (SIP_PAGE3_SNOM_AOC | SIP_PAGE3_PRACK | SIP_PAGE3_DIRECT_MEDIA_OUTGOING | SIP_PAGE3_POORMANSPLC)
/*@}*/
Modified: team/oej/pinetestedition-1.8/configs/rtp.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinetestedition-1.8/configs/rtp.conf.sample?view=diff&rev=383465&r1=383464&r2=383465
==============================================================================
--- team/oej/pinetestedition-1.8/configs/rtp.conf.sample (original)
+++ team/oej/pinetestedition-1.8/configs/rtp.conf.sample Wed Mar 20 16:07:21 2013
@@ -32,3 +32,20 @@
; 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.
+; This setting apply to ALL rtp streams in this Asterisk instance.
+; If you have video or text streams, it might not be a good idea.
+;
+; You can turn this on per device or globally in sip.conf too.
+;plc=yes
Modified: team/oej/pinetestedition-1.8/include/asterisk/rtp_engine.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinetestedition-1.8/include/asterisk/rtp_engine.h?view=diff&rev=383465&r1=383464&r2=383465
==============================================================================
--- team/oej/pinetestedition-1.8/include/asterisk/rtp_engine.h (original)
+++ team/oej/pinetestedition-1.8/include/asterisk/rtp_engine.h Wed Mar 20 16:07:21 2013
@@ -428,6 +428,8 @@
/*! Callback to set translation information for the CQR record */
void (*set_translator) (struct ast_rtp_instance *instance, const char *readtranslator, const int readcost, const char *writetranslator, const int writecost);
int (*rtcp_write_empty)(struct ast_rtp_instance *instance);
+ /*! Callback to turn on or off poor man's packet loss concealment in the RTP engine */
+ void (*plc_set_state)(struct ast_rtp_instance *instance, int state);
/*! Linked list information */
AST_RWLIST_ENTRY(ast_rtp_engine) entry;
};
@@ -1993,6 +1995,13 @@
*/
int ast_rtp_instance_set_translator(struct ast_rtp_instance *instance, const char *readtranslator, const int readcost, const char *writetranslator, const int writecost);
+/*!
+ * \brief Change state of PLC for RTP instance
+ * \param instance the RTP instance
+ * \param state 1 for on, 0 for off
+ */
+void ast_rtp_instance_plc_set_state(struct ast_rtp_instance *instance, int state);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
Modified: team/oej/pinetestedition-1.8/main/rtp_engine.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinetestedition-1.8/main/rtp_engine.c?view=diff&rev=383465&r1=383464&r2=383465
==============================================================================
--- team/oej/pinetestedition-1.8/main/rtp_engine.c (original)
+++ team/oej/pinetestedition-1.8/main/rtp_engine.c Wed Mar 20 16:07:21 2013
@@ -797,6 +797,14 @@
instance->engine->stop(instance);
}
}
+
+void ast_rtp_instance_plc_set_state(struct ast_rtp_instance *instance, int state)
+{
+ if (instance->engine->plc_set_state) {
+ instance->engine->plc_set_state(instance, state);
+ }
+}
+
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
{
Added: team/oej/pinetestedition-1.8/patches/pinefool-poor-mans-plc-1.8.diff
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinetestedition-1.8/patches/pinefool-poor-mans-plc-1.8.diff?view=auto&rev=383465
==============================================================================
--- team/oej/pinetestedition-1.8/patches/pinefool-poor-mans-plc-1.8.diff (added)
+++ team/oej/pinetestedition-1.8/patches/pinefool-poor-mans-plc-1.8.diff Wed Mar 20 16:07:21 2013
@@ -1,0 +1,326 @@
+Index: channels/chan_sip.c
+===================================================================
+--- channels/chan_sip.c (.../branches/1.8) (revision 383463)
++++ channels/chan_sip.c (.../team/oej/pinefool-poor-mans-plc-1.8) (revision 383463)
+@@ -5595,6 +5595,10 @@
+
+ ast_rtp_instance_set_prop(dialog->trtp, AST_RTP_PROPERTY_RTCP, 1);
+ }
++ if (ast_test_flag(&dialog->flags[2], SIP_PAGE3_POORMANSPLC)) {
++ /* This is only supported for AUDIO */
++ ast_rtp_instance_plc_set_state(dialog->rtp, TRUE);
++ }
+
+ ast_rtp_instance_set_timeout(dialog->rtp, dialog->rtptimeout);
+ ast_rtp_instance_set_hold_timeout(dialog->rtp, dialog->rtpholdtimeout);
+@@ -18093,6 +18097,7 @@
+ ast_cli(fd, " Dynamic : %s\n", AST_CLI_YESNO(peer->host_dynamic));
+ ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
+ ast_cli(fd, " MaxCallBR : %d kbps\n", peer->maxcallbitrate);
++ ast_cli(fd, " PLC : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[2], SIP_PAGE3_POORMANSPLC)));
+ ast_cli(fd, " Expire : %ld\n", ast_sched_when(sched, peer->expire));
+ ast_cli(fd, " Insecure : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
+ ast_cli(fd, " Force rport : %s\n", AST_CLI_YESNO(ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT)));
+@@ -18785,6 +18790,7 @@
+ ast_cli(a->fd, " Relax DTMF: %s\n", AST_CLI_YESNO(global_relaxdtmf));
+ ast_cli(a->fd, " RFC2833 Compensation: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE)));
+ ast_cli(a->fd, " Symmetric RTP: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[1], SIP_PAGE2_SYMMETRICRTP)));
++ ast_cli(a->fd, " Poor man's PLC: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[2], SIP_PAGE3_POORMANSPLC)));
+ ast_cli(a->fd, " Compact SIP headers: %s\n", AST_CLI_YESNO(sip_cfg.compactheaders));
+ ast_cli(a->fd, " RTP Keepalive: %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
+ ast_cli(a->fd, " RTP Timeout: %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
+@@ -19194,6 +19200,7 @@
+ ast_cli(a->fd, " T.38 support %s\n", AST_CLI_YESNO(cur->udptl != NULL));
+ ast_cli(a->fd, " Video support %s\n", AST_CLI_YESNO(cur->vrtp != NULL));
+ ast_cli(a->fd, " MaxCallBR: %d kbps\n", cur->maxcallbitrate);
++ ast_cli(a->fd, " Poor man's PLC: %s\n", AST_CLI_YESNO(ast_test_flag(&cur->flags[2], SIP_PAGE3_POORMANSPLC)));
+ ast_cli(a->fd, " Theoretical Address: %s\n", ast_sockaddr_stringify(&cur->sa));
+ ast_cli(a->fd, " Received Address: %s\n", ast_sockaddr_stringify(&cur->recv));
+ ast_cli(a->fd, " SIP Transfer mode: %s\n", transfermode2str(cur->allowtransfer));
+@@ -27477,6 +27484,10 @@
+ ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
+ ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
+ }
++ } else if (!strcasecmp(v->name, "plc")) {
++ if (ast_true(v->value)) {
++ ast_set_flag(&flags[2], SIP_PAGE3_POORMANSPLC);
++ }
+ } else if (!strcasecmp(v->name, "nat")) {
+ ast_set_flag(&mask[0], SIP_NAT_FORCE_RPORT);
+ ast_set_flag(&flags[0], SIP_NAT_FORCE_RPORT); /* Default to "force_rport" */
+Index: channels/sip/include/sip.h
+===================================================================
+--- channels/sip/include/sip.h (.../branches/1.8) (revision 383463)
++++ channels/sip/include/sip.h (.../team/oej/pinefool-poor-mans-plc-1.8) (revision 383463)
+@@ -359,9 +359,10 @@
+
+ #define SIP_PAGE3_SNOM_AOC (1 << 0) /*!< DPG: Allow snom aoc messages */
+ #define SIP_PAGE3_DIRECT_MEDIA_OUTGOING (1 << 1) /*!< DP: Only send direct media reinvites on outgoing calls */
++#define SIP_PAGE3_POORMANSPLC (1 << 28) /*!< DPG: Enable poor man's PLC - packet loss concealment */
+
+ #define SIP_PAGE3_FLAGS_TO_COPY \
+- (SIP_PAGE3_SNOM_AOC | SIP_PAGE3_DIRECT_MEDIA_OUTGOING)
++ (SIP_PAGE3_SNOM_AOC | SIP_PAGE3_DIRECT_MEDIA_OUTGOING | SIP_PAGE3_POORMANSPLC)
+
+ /*@}*/
+
+Index: funcs/func_curl.c
+===================================================================
+--- funcs/func_curl.c (.../branches/1.8) (revision 383463)
++++ funcs/func_curl.c (.../team/oej/pinefool-poor-mans-plc-1.8) (revision 383463)
+@@ -568,7 +568,6 @@
+ struct ast_datastore *store = NULL;
+ int hashcompat = 0;
+ AST_LIST_HEAD(global_curl_info, curl_settings) *list = NULL;
+- char curl_errbuf[CURL_ERROR_SIZE + 1]; /* add one to be safe */
+
+ if (buf) {
+ *buf = '\0';
+@@ -630,20 +629,8 @@
+ curl_easy_setopt(*curl, CURLOPT_POSTFIELDS, args.postdata);
+ }
+
+- /* Temporarily assign a buffer for curl to write errors to. */
+- curl_errbuf[0] = curl_errbuf[CURL_ERROR_SIZE] = '\0';
+- curl_easy_setopt(*curl, CURLOPT_ERRORBUFFER, curl_errbuf);
++ curl_easy_perform(*curl);
+
+- if (curl_easy_perform(*curl) != 0) {
+- ast_log(LOG_WARNING, "%s ('%s')\n", curl_errbuf, args.url);
+- }
+-
+- /* Reset buffer to NULL so curl doesn't try to write to it when the
+- * buffer is deallocated. Documentation is vague about allowing NULL
+- * here, but the source allows it. See: "typecheck: allow NULL to unset
+- * CURLOPT_ERRORBUFFER" (62bcf005f4678a93158358265ba905bace33b834). */
+- curl_easy_setopt(*curl, CURLOPT_ERRORBUFFER, (char*)NULL);
+-
+ if (store) {
+ AST_LIST_UNLOCK(list);
+ }
+Index: include/asterisk/rtp_engine.h
+===================================================================
+--- include/asterisk/rtp_engine.h (.../branches/1.8) (revision 383463)
++++ include/asterisk/rtp_engine.h (.../team/oej/pinefool-poor-mans-plc-1.8) (revision 383463)
+@@ -377,6 +377,8 @@
+ format_t (*available_formats)(struct ast_rtp_instance *instance, format_t to_endpoint, format_t to_asterisk);
+ /*! Callback to send CNG */
+ int (*sendcng)(struct ast_rtp_instance *instance, int level);
++ /*! Callback to turn on or off poor man's packet loss concealment in the RTP engine */
++ void (*plc_set_state)(struct ast_rtp_instance *instance, int state);
+ /*! Linked list information */
+ AST_RWLIST_ENTRY(ast_rtp_engine) entry;
+ };
+@@ -1854,6 +1856,13 @@
+ */
+ struct ast_srtp *ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance);
+
++/*!
++ * \brief Change state of PLC for RTP instance
++ * \param instance the RTP instance
++ * \param state 1 for on, 0 for off
++ */
++void ast_rtp_instance_plc_set_state(struct ast_rtp_instance *instance, int state);
++
+ #if defined(__cplusplus) || defined(c_plusplus)
+ }
+ #endif
+Index: main/rtp_engine.c
+===================================================================
+--- main/rtp_engine.c (.../branches/1.8) (revision 383463)
++++ main/rtp_engine.c (.../team/oej/pinefool-poor-mans-plc-1.8) (revision 383463)
+@@ -783,6 +783,14 @@
+ }
+ }
+
++void ast_rtp_instance_plc_set_state(struct ast_rtp_instance *instance, int state)
++{
++ if (instance->engine->plc_set_state) {
++ instance->engine->plc_set_state(instance, state);
++ }
++}
++
++
+ int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
+ {
+ return instance->engine->fd ? instance->engine->fd(instance, rtcp) : -1;
+Index: configs/rtp.conf.sample
+===================================================================
+--- configs/rtp.conf.sample (.../branches/1.8) (revision 383463)
++++ configs/rtp.conf.sample (.../team/oej/pinefool-poor-mans-plc-1.8) (revision 383463)
+@@ -32,3 +32,20 @@
+ ; 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.
++; This setting apply to ALL rtp streams in this Asterisk instance.
++; If you have video or text streams, it might not be a good idea.
++;
++; You can turn this on per device or globally in sip.conf too.
++;plc=yes
+Index: res/res_rtp_asterisk.c
+===================================================================
+--- res/res_rtp_asterisk.c (.../branches/1.8) (revision 383463)
++++ res/res_rtp_asterisk.c (.../team/oej/pinefool-poor-mans-plc-1.8) (revision 383463)
+@@ -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? */
+@@ -113,11 +114,13 @@
+ #define FLAG_NAT_INACTIVE_NOWARN (1 << 1)
+ #define FLAG_NEED_MARKER_BIT (1 << 3)
+ #define FLAG_DTMF_COMPENSATE (1 << 4)
++#define FLAG_POORMANSPLC (1 << 15)
+
+ /*! \brief RTP session description */
+ 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 */
+@@ -293,11 +296,13 @@
+ static void ast_rtp_stop(struct ast_rtp_instance *instance);
+ static int ast_rtp_qos_set(struct ast_rtp_instance *instance, int tos, int cos, const char* desc);
+ static int ast_rtp_sendcng(struct ast_rtp_instance *instance, int level);
++static void ast_rtp_plc_set_state(struct ast_rtp_instance *instance, int state);
+
+ /* RTP Engine Declaration */
+ static struct ast_rtp_engine asterisk_rtp_engine = {
+ .name = "asterisk",
+ .new = ast_rtp_new,
++ .plc_set_state = ast_rtp_plc_set_state,
+ .destroy = ast_rtp_destroy,
+ .dtmf_begin = ast_rtp_dtmf_begin,
+ .dtmf_end = ast_rtp_dtmf_end,
+@@ -529,6 +534,11 @@
+ }
+
+ /* Set default parameters on the newly created RTP structure */
++ rtp->plcbuf = NULL;
++
++ if (poormansplc) {
++ ast_set_flag(rtp, FLAG_POORMANSPLC); /* If PLC is globally set, turn it on */
++ }
+ rtp->ssrc = ast_random();
+ rtp->seqno = ast_random() & 0xffff;
+ rtp->strict_rtp_state = (strictrtp ? STRICT_RTP_LEARN : STRICT_RTP_OPEN);
+@@ -613,6 +623,9 @@
+ AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
+ ast_free(rtp->red);
+ }
++ if (rtp->plcbuf != NULL) {
++ ast_frfree(rtp->plcbuf);
++ }
+
+ /* Finally destroy ourselves */
+ ast_free(rtp);
+@@ -1150,6 +1163,16 @@
+ return res;
+ }
+
++static void ast_rtp_plc_set_state(struct ast_rtp_instance *instance, int state)
++{
++ struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
++ if (state) {
++ ast_set_flag(rtp, FLAG_POORMANSPLC);
++ } else {
++ ast_clear_flag(rtp, FLAG_POORMANSPLC);
++ }
++}
++
+ static int ast_rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame *frame, int codec)
+ {
+ struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+@@ -2126,6 +2149,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) {
+@@ -2327,6 +2351,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 (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;
++ }
++ 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 (ast_test_flag(rtp, FLAG_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 +2541,15 @@
+ rtp->f.delivery.tv_usec = 0;
+ }
+
++ if (ast_test_flag(rtp, FLAG_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 +3035,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 +3069,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)) {
Propchange: team/oej/pinetestedition-1.8/patches/pinefool-poor-mans-plc-1.8.diff
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/pinetestedition-1.8/patches/pinefool-poor-mans-plc-1.8.diff
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/oej/pinetestedition-1.8/patches/pinefool-poor-mans-plc-1.8.diff
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/oej/pinetestedition-1.8/res/res_rtp_asterisk.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pinetestedition-1.8/res/res_rtp_asterisk.c?view=diff&rev=383465&r1=383464&r2=383465
==============================================================================
--- team/oej/pinetestedition-1.8/res/res_rtp_asterisk.c (original)
+++ team/oej/pinetestedition-1.8/res/res_rtp_asterisk.c Wed Mar 20 16:07:21 2013
@@ -107,6 +107,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 gathering stats? */
@@ -143,11 +144,13 @@
#define FLAG_DTMF_COMPENSATE (1 << 4)
#define FLAG_CN_ACTIVE (1 << 5)
#define FLAG_HOLD (1 << 6)
+#define FLAG_POORMANSPLC (1 << 7)
/*! \brief RTP session description */
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 */
@@ -360,6 +363,7 @@
static int add_sdes_bodypart(struct ast_rtp *rtp, unsigned int *rtcp_packet, int len, int type);
static int add_sdes_header(struct ast_rtp *rtp, unsigned int *rtcp_packet, int len);
static int ast_rtcp_write_empty_frame(struct ast_rtp_instance *instance);
+static void ast_rtp_plc_set_state(struct ast_rtp_instance *instance, int state);
/* RTP Engine Declaration */
static struct ast_rtp_engine asterisk_rtp_engine = {
@@ -395,6 +399,7 @@
.set_translator = ast_rtcp_set_translator,
.isactive = ast_rtp_isactive,
.rtcp_write_empty = ast_rtcp_write_empty_frame,
+ .plc_set_state = ast_rtp_plc_set_state,
};
/*! * \page DTMFQUEUE Queue for outbound DTMF events
@@ -640,6 +645,11 @@
}
/* Set default parameters on the newly created RTP structure */
+ rtp->plcbuf = NULL;
+
+ if (poormansplc) {
+ ast_set_flag(rtp, FLAG_POORMANSPLC); /* If PLC is globally set, turn it on */
+ }
rtp->ssrc = ast_random();
rtp->seqno = ast_random() & 0xffff;
rtp->strict_rtp_state = (strictrtp ? STRICT_RTP_LEARN : STRICT_RTP_OPEN);
@@ -721,6 +731,9 @@
*/
close(rtp->rtcp->s);
ast_free(rtp->rtcp);
+ }
+ if (rtp->plcbuf != NULL) {
+ ast_frfree(rtp->plcbuf);
}
/* Destroy RED if it was being used */
@@ -1365,6 +1378,16 @@
}
return res;
+}
+
+static void ast_rtp_plc_set_state(struct ast_rtp_instance *instance, int state)
+{
+ struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+ if (state) {
+ ast_set_flag(rtp, FLAG_POORMANSPLC);
+ } else {
+ ast_clear_flag(rtp, FLAG_POORMANSPLC);
+ }
}
static int ast_rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame *frame, int codec)
@@ -2555,6 +2578,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) {
@@ -2760,6 +2784,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 (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;
+ }
+ 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 (ast_test_flag(rtp, FLAG_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;
@@ -2945,6 +2993,15 @@
rtp->f.delivery.tv_usec = 0;
}
+ if (ast_test_flag(rtp, FLAG_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);
}
@@ -3692,6 +3749,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"))) {
@@ -3725,6 +3783,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