aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authortwilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b>2010-03-13 00:30:04 +0000
committertwilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b>2010-03-13 00:30:04 +0000
commit8b997b6ae37cf53d86a1918be28dfc999d4d1ee0 (patch)
tree2f54dbec9891bf51682d9e18092aa7d98ebe3384 /main
parent3be293b2e1a22b1b3b42f7952ecb72a8773522c5 (diff)
Merged revisions 252089 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ........ r252089 | twilson | 2010-03-12 16:04:51 -0600 (Fri, 12 Mar 2010) | 20 lines Only change the RTP ssrc when we see that it has changed This change basically reverts the change reviewed in https://reviewboard.asterisk.org/r/374/ and instead limits the updating of the RTP synchronization source to only those times when we detect that the other side of the conversation has changed the ssrc. The problem is that SRCUPDATE control frames are sent many times where we don't want a new ssrc, including whenever Asterisk has to send DTMF in a normal bridge. This is also not the first time that this mistake has been made. The initial implementation of the ast_rtp_new_source function also changed the ssrc--and then it was removed because of this same issue. Then, we put it back in again to fix a different issue. This patch attempts to only change the ssrc when we see that the other side of the conversation has changed the ssrc. It also renames some functions to make their purpose more clear. Review: https://reviewboard.asterisk.org/r/540/ ........ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@252175 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r--main/channel.c5
-rw-r--r--main/rtp.c57
2 files changed, 47 insertions, 15 deletions
diff --git a/main/channel.c b/main/channel.c
index a4ffd629d..4141d51bf 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -1972,6 +1972,7 @@ int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
case AST_CONTROL_RINGING:
case AST_CONTROL_ANSWER:
case AST_CONTROL_SRCUPDATE:
+ case AST_CONTROL_SRCCHANGE:
/* Unimportant */
break;
default:
@@ -2571,6 +2572,7 @@ static int attribute_const is_visible_indication(enum ast_control_frame_type con
case AST_CONTROL_PROCEEDING:
case AST_CONTROL_VIDUPDATE:
case AST_CONTROL_SRCUPDATE:
+ case AST_CONTROL_SRCCHANGE:
case AST_CONTROL_RADIO_KEY:
case AST_CONTROL_RADIO_UNKEY:
case AST_CONTROL_OPTION:
@@ -2663,6 +2665,7 @@ int ast_indicate_data(struct ast_channel *chan, int _condition,
case AST_CONTROL_PROCEEDING:
case AST_CONTROL_VIDUPDATE:
case AST_CONTROL_SRCUPDATE:
+ case AST_CONTROL_SRCCHANGE:
case AST_CONTROL_RADIO_KEY:
case AST_CONTROL_RADIO_UNKEY:
case AST_CONTROL_OPTION:
@@ -3367,6 +3370,7 @@ struct ast_channel *__ast_request_and_dial(const char *type, int format, void *d
case AST_CONTROL_UNHOLD:
case AST_CONTROL_VIDUPDATE:
case AST_CONTROL_SRCUPDATE:
+ case AST_CONTROL_SRCCHANGE:
case -1: /* Ignore -- just stopping indications */
break;
@@ -4316,6 +4320,7 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
case AST_CONTROL_UNHOLD:
case AST_CONTROL_VIDUPDATE:
case AST_CONTROL_SRCUPDATE:
+ case AST_CONTROL_SRCCHANGE:
ast_indicate_data(other, f->subclass, f->data, f->datalen);
if (jb_in_use) {
ast_jb_empty_and_reset(c0, c1);
diff --git a/main/rtp.c b/main/rtp.c
index 4f54b71a5..76deb3c69 100644
--- a/main/rtp.c
+++ b/main/rtp.c
@@ -174,7 +174,6 @@ struct ast_rtp {
struct ast_codec_pref pref;
struct ast_rtp *bridged; /*!< Who we are Packet bridged to */
int set_marker_bit:1; /*!< Whether to set the marker bit or not */
- unsigned int constantssrc:1;
};
/* Forward declarations */
@@ -1175,6 +1174,7 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
unsigned int *rtpheader;
struct rtpPayloadType rtpPT;
struct ast_rtp *bridged = NULL;
+ AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
/* If time is up, kill it */
if (rtp->sending_digit)
@@ -1253,11 +1253,23 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
seqno &= 0xffff;
timestamp = ntohl(rtpheader[1]);
ssrc = ntohl(rtpheader[2]);
-
- if (!mark && rtp->rxssrc && rtp->rxssrc != ssrc) {
- if (option_debug || rtpdebug)
- ast_log(LOG_DEBUG, "Forcing Marker bit, because SSRC has changed\n");
- mark = 1;
+
+ AST_LIST_HEAD_INIT_NOLOCK(&frames);
+ /* Force a marker bit and change SSRC if the SSRC changes */
+ if (rtp->rxssrc && rtp->rxssrc != ssrc) {
+ struct ast_frame *f, srcupdate = {
+ AST_FRAME_CONTROL,
+ .subclass = AST_CONTROL_SRCCHANGE,
+ };
+
+ if (!mark) {
+ if (option_debug || rtpdebug) {
+ ast_log(LOG_DEBUG, "Forcing Marker bit, because SSRC has changed\n");
+ }
+ mark = 1;
+ }
+ f = ast_frisolate(&srcupdate);
+ AST_LIST_INSERT_TAIL(&frames, f, frame_list);
}
rtp->rxssrc = ssrc;
@@ -1280,7 +1292,7 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
if (res < hdrlen) {
ast_log(LOG_WARNING, "RTP Read too short (%d, expecting %d)\n", res, hdrlen);
- return &ast_null_frame;
+ return AST_LIST_FIRST(&frames) ? AST_LIST_FIRST(&frames) : &ast_null_frame;
}
rtp->rxcount++; /* Only count reasonably valid packets, this'll make the rtcp stats more accurate */
@@ -1342,7 +1354,11 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
} else {
ast_log(LOG_NOTICE, "Unknown RTP codec %d received from '%s'\n", payloadtype, ast_inet_ntoa(rtp->them.sin_addr));
}
- return f ? f : &ast_null_frame;
+ if (f) {
+ AST_LIST_INSERT_TAIL(&frames, f, frame_list);
+ return AST_LIST_FIRST(&frames);
+ }
+ return &ast_null_frame;
}
rtp->lastrxformat = rtp->f.subclass = rtpPT.code;
rtp->f.frametype = (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) ? AST_FRAME_VOICE : AST_FRAME_VIDEO;
@@ -1358,7 +1374,8 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(f->subclass)), ast_tv(0, 0));
rtp->resp = 0;
rtp->dtmf_timeout = rtp->dtmf_duration = 0;
- return f;
+ AST_LIST_INSERT_TAIL(&frames, f, frame_list);
+ return AST_LIST_FIRST(&frames);
}
}
@@ -1391,7 +1408,9 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
rtp->f.subclass |= 0x1;
}
rtp->f.src = "RTP";
- return &rtp->f;
+
+ AST_LIST_INSERT_TAIL(&frames, &rtp->f, frame_list);
+ return AST_LIST_FIRST(&frames);
}
/* The following array defines the MIME Media type (and subtype) for each
@@ -2063,18 +2082,26 @@ int ast_rtp_settos(struct ast_rtp *rtp, int tos)
return res;
}
-void ast_rtp_set_constantssrc(struct ast_rtp *rtp)
+void ast_rtp_update_source(struct ast_rtp *rtp)
{
- rtp->constantssrc = 1;
+ if (rtp) {
+ rtp->set_marker_bit = 1;
+ if (option_debug > 2) {
+ ast_log(LOG_DEBUG, "Setting the marker bit due to a source update\n");
+ }
+ }
}
-void ast_rtp_new_source(struct ast_rtp *rtp)
+void ast_rtp_change_source(struct ast_rtp *rtp)
{
if (rtp) {
+ unsigned int ssrc = ast_random();
+
rtp->set_marker_bit = 1;
- if (!rtp->constantssrc) {
- rtp->ssrc = ast_random();
+ if (option_debug > 2) {
+ ast_log(LOG_DEBUG, "Changing ssrc from %u to %u due to a source change\n", rtp->ssrc, ssrc);
}
+ rtp->ssrc = ssrc;
}
}