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: https://origsvn.digium.com/svn/asterisk/branches/1.4@252175 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Terry Wilson
2010-03-13 00:30:04 +00:00
parent a247e69d65
commit 529e8af144
9 changed files with 79 additions and 54 deletions

View File

@@ -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,21 +2082,29 @@ int ast_rtp_settos(struct ast_rtp *rtp, int tos)
return res;
}
void ast_rtp_set_constantssrc(struct ast_rtp *rtp)
{
rtp->constantssrc = 1;
}
void ast_rtp_new_source(struct ast_rtp *rtp)
void ast_rtp_update_source(struct ast_rtp *rtp)
{
if (rtp) {
rtp->set_marker_bit = 1;
if (!rtp->constantssrc) {
rtp->ssrc = ast_random();
if (option_debug > 2) {
ast_log(LOG_DEBUG, "Setting the marker bit due to a source update\n");
}
}
}
void ast_rtp_change_source(struct ast_rtp *rtp)
{
if (rtp) {
unsigned int ssrc = ast_random();
rtp->set_marker_bit = 1;
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;
}
}
void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
{
rtp->them.sin_port = them->sin_port;