[svn-commits] twilson: trunk r252089 - in /trunk: addons/ channels/ channels/sip/include/ c...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Mar 12 16:04:56 CST 2010


Author: twilson
Date: Fri Mar 12 16:04:51 2010
New Revision: 252089

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=252089
Log:
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.


Modified:
    trunk/addons/chan_ooh323.c
    trunk/channels/chan_h323.c
    trunk/channels/chan_mgcp.c
    trunk/channels/chan_sip.c
    trunk/channels/chan_skinny.c
    trunk/channels/sip/include/sip.h
    trunk/configs/sip.conf.sample
    trunk/include/asterisk/frame.h
    trunk/include/asterisk/rtp_engine.h
    trunk/main/channel.c
    trunk/main/rtp_engine.c
    trunk/res/res_rtp_asterisk.c

Modified: trunk/addons/chan_ooh323.c
URL: http://svnview.digium.com/svn/asterisk/trunk/addons/chan_ooh323.c?view=diff&rev=252089&r1=252088&r2=252089
==============================================================================
--- trunk/addons/chan_ooh323.c (original)
+++ trunk/addons/chan_ooh323.c Fri Mar 12 16:04:51 2010
@@ -1206,10 +1206,12 @@
 	    		ooManualRingback(callToken);
 	    }
 	 break;
-      case AST_CONTROL_SRCUPDATE:
-		ast_rtp_instance_new_source(p->rtp);
+	case AST_CONTROL_SRCUPDATE:
+		ast_rtp_instance_update_source(p->rtp);
 		break;
-
+	case AST_CONTROL_SRCCHANGE:
+		ast_rtp_instance_change_source(p->rtp);
+		break;
       case AST_CONTROL_CONNECTED_LINE:
 		if (gH323Debug)
 			ast_log(LOG_DEBUG, "Sending connected line info for %s (%s)\n",

Modified: trunk/channels/chan_h323.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_h323.c?view=diff&rev=252089&r1=252088&r2=252089
==============================================================================
--- trunk/channels/chan_h323.c (original)
+++ trunk/channels/chan_h323.c Fri Mar 12 16:04:51 2010
@@ -914,7 +914,11 @@
 		res = 0;
 		break;
 	case AST_CONTROL_SRCUPDATE:
-		ast_rtp_instance_new_source(pvt->rtp);
+		ast_rtp_instance_update_source(pvt->rtp);
+		res = 0;
+		break;
+	case AST_CONTROL_SRCCHANGE:
+		ast_rtp_instance_change_source(pvt->rtp);
 		res = 0;
 		break;
 	case AST_CONTROL_PROCEEDING:

Modified: trunk/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_mgcp.c?view=diff&rev=252089&r1=252088&r2=252089
==============================================================================
--- trunk/channels/chan_mgcp.c (original)
+++ trunk/channels/chan_mgcp.c Fri Mar 12 16:04:51 2010
@@ -1456,7 +1456,10 @@
 		ast_moh_stop(ast);
 		break;
 	case AST_CONTROL_SRCUPDATE:
-		ast_rtp_instance_new_source(sub->rtp);
+		ast_rtp_instance_update_source(sub->rtp);
+		break;
+	case AST_CONTROL_SRCCHANGE:
+		ast_rtp_instance_change_source(sub->rtp);
 		break;
 	case AST_CONTROL_PROGRESS:
 	case AST_CONTROL_PROCEEDING:

Modified: trunk/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_sip.c?view=diff&rev=252089&r1=252088&r2=252089
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Fri Mar 12 16:04:51 2010
@@ -3903,7 +3903,6 @@
 	if (dialog->rtp) { /* Audio */
 		ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
 		ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
-		ast_rtp_instance_set_prop(dialog->rtp, AST_RTP_PROPERTY_CONSTANT_SSRC, ast_test_flag(&dialog->flags[1], SIP_PAGE2_CONSTANT_SSRC));
 		ast_rtp_instance_set_timeout(dialog->rtp, peer->rtptimeout);
 		ast_rtp_instance_set_hold_timeout(dialog->rtp, peer->rtpholdtimeout);
 		/* Set Frame packetization */
@@ -3913,7 +3912,6 @@
 	if (dialog->vrtp) { /* Video */
 		ast_rtp_instance_set_timeout(dialog->vrtp, peer->rtptimeout);
 		ast_rtp_instance_set_hold_timeout(dialog->vrtp, peer->rtpholdtimeout);
-		ast_rtp_instance_set_prop(dialog->vrtp, AST_RTP_PROPERTY_CONSTANT_SSRC, ast_test_flag(&dialog->flags[1], SIP_PAGE2_CONSTANT_SSRC));
 	}
 	if (dialog->trtp) { /* Realtime text */
 		ast_rtp_instance_set_timeout(dialog->trtp, peer->rtptimeout);
@@ -4970,7 +4968,7 @@
 
 		ast_setstate(ast, AST_STATE_UP);
 		ast_debug(1, "SIP answering channel: %s\n", ast->name);
-		ast_rtp_instance_new_source(p->rtp);
+		ast_rtp_instance_update_source(p->rtp);
 		res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, FALSE, TRUE);
 		ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
 	}
@@ -5002,7 +5000,7 @@
 				if ((ast->_state != AST_STATE_UP) &&
 				    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
 				    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
-					ast_rtp_instance_new_source(p->rtp);
+					ast_rtp_instance_update_source(p->rtp);
 					if (!global_prematuremediafilter) {
 						p->invitestate = INV_EARLY_MEDIA;
 						transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
@@ -5333,11 +5331,11 @@
 		res = -1;
 		break;
 	case AST_CONTROL_HOLD:
-		ast_rtp_instance_new_source(p->rtp);
+		ast_rtp_instance_update_source(p->rtp);
 		ast_moh_start(ast, data, p->mohinterpret);
 		break;
 	case AST_CONTROL_UNHOLD:
-		ast_rtp_instance_new_source(p->rtp);
+		ast_rtp_instance_update_source(p->rtp);
 		ast_moh_stop(ast);
 		break;
 	case AST_CONTROL_VIDUPDATE:	/* Request a video frame update */
@@ -5356,7 +5354,10 @@
 		}
 		break;
 	case AST_CONTROL_SRCUPDATE:
-		ast_rtp_instance_new_source(p->rtp);
+		ast_rtp_instance_update_source(p->rtp);
+		break;
+	case AST_CONTROL_SRCCHANGE:
+		ast_rtp_instance_change_source(p->rtp);
 		break;
 	case AST_CONTROL_CONNECTED_LINE:
 		update_connectedline(p, data, datalen);
@@ -19232,12 +19233,6 @@
 				res = -1;
 				goto request_invite_cleanup;
 			}
-			if (p->rtp) {
-				ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_CONSTANT_SSRC, ast_test_flag(&p->flags[1], SIP_PAGE2_CONSTANT_SSRC));
-			}
-			if (p->vrtp) {
-				ast_rtp_instance_set_prop(p->vrtp, AST_RTP_PROPERTY_CONSTANT_SSRC, ast_test_flag(&p->flags[1], SIP_PAGE2_CONSTANT_SSRC));
-			}
 		} else {	/* No SDP in invite, call control session */
 			p->jointcapability = p->capability;
 			ast_debug(2, "No SDP in Invite, third party call control\n");
@@ -22595,9 +22590,6 @@
 	} else if (!strcasecmp(v->name, "buggymwi")) {
 		ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
 		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
-	} else if (!strcasecmp(v->name, "constantssrc")) {
-		ast_set_flag(&mask[1], SIP_PAGE2_CONSTANT_SSRC);
-		ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_CONSTANT_SSRC);
 	} else
 		res = 0;
 

Modified: trunk/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_skinny.c?view=diff&rev=252089&r1=252088&r2=252089
==============================================================================
--- trunk/channels/chan_skinny.c (original)
+++ trunk/channels/chan_skinny.c Fri Mar 12 16:04:51 2010
@@ -4304,7 +4304,10 @@
 	case AST_CONTROL_PROCEEDING:
 		break;
 	case AST_CONTROL_SRCUPDATE:
-		ast_rtp_instance_new_source(sub->rtp);
+		ast_rtp_instance_update_source(sub->rtp);
+		break;
+	case AST_CONTROL_SRCCHANGE:
+		ast_rtp_instance_change_source(sub->rtp);
 		break;
 	case AST_CONTROL_CONNECTED_LINE:
 		update_connectedline(sub, data, datalen);

Modified: trunk/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/sip/include/sip.h?view=diff&rev=252089&r1=252088&r2=252089
==============================================================================
--- trunk/channels/sip/include/sip.h (original)
+++ trunk/channels/sip/include/sip.h Fri Mar 12 16:04:51 2010
@@ -308,7 +308,6 @@
 #define SIP_PAGE2_Q850_REASON           (1 << 4)    /*!< DP: Get/send cause code via Reason header */
 
 /* Space for addition of other realtime flags in the future */
-#define SIP_PAGE2_CONSTANT_SSRC         (1 << 7)    /*!< GDP: Don't change SSRC on reinvite */
 #define SIP_PAGE2_SYMMETRICRTP          (1 << 8)    /*!< GDP: Whether symmetric RTP is enabled or not */
 #define SIP_PAGE2_STATECHANGEQUEUE      (1 << 9)    /*!< D: Unsent state pending change exists */
 
@@ -346,7 +345,7 @@
 	SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | \
 	SIP_PAGE2_BUGGY_MWI | SIP_PAGE2_TEXTSUPPORT | SIP_PAGE2_FAX_DETECT | \
 	SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_VIDEOSUPPORT_ALWAYS | SIP_PAGE2_PREFERRED_CODEC | \
-	SIP_PAGE2_RPID_IMMEDIATE | SIP_PAGE2_RPID_UPDATE | SIP_PAGE2_SYMMETRICRTP | SIP_PAGE2_CONSTANT_SSRC |\
+	SIP_PAGE2_RPID_IMMEDIATE | SIP_PAGE2_RPID_UPDATE | SIP_PAGE2_SYMMETRICRTP |\
 	SIP_PAGE2_Q850_REASON)
 
 /*@}*/

Modified: trunk/configs/sip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/trunk/configs/sip.conf.sample?view=diff&rev=252089&r1=252088&r2=252089
==============================================================================
--- trunk/configs/sip.conf.sample (original)
+++ trunk/configs/sip.conf.sample Fri Mar 12 16:04:51 2010
@@ -788,8 +788,6 @@
                                 ; also contains the Asterisk version.
 ;sdpowner=root                  ; Allows you to change the username field in the SDP owner string, (o=)
                                 ; This field MUST NOT contain spaces
-
-;constantssrc=yes               ; Don't change the RTP SSRC when our media stream changes
 
 ;----------------------------------------- REALTIME SUPPORT ------------------------
 ; For additional information on ARA, the Asterisk Realtime Architecture,
@@ -1003,7 +1001,6 @@
 ; timerb
 ; qualifyfreq
 ; t38pt_usertpsource
-; constantssrc
 ; contactpermit         ; Limit what a host may register as (a neat trick
 ; contactdeny           ; is to register at the same IP as a SIP provider,
 ;                       ; then call oneself, and get redirected to that

Modified: trunk/include/asterisk/frame.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/frame.h?view=diff&rev=252089&r1=252088&r2=252089
==============================================================================
--- trunk/include/asterisk/frame.h (original)
+++ trunk/include/asterisk/frame.h Fri Mar 12 16:04:51 2010
@@ -85,7 +85,8 @@
  * \arg \b HOLD            Call is placed on hold
  * \arg \b UNHOLD          Call is back from hold
  * \arg \b VIDUPDATE       Video update requested
- * \arg \b SRCUPDATE       The source of media has changed
+ * \arg \b SRCUPDATE       The source of media has changed (RTP marker bit must change)
+ * \arg \b SRCCHANGE       Media source has changed (RTP marker bit and SSRC must change)
  * \arg \b CONNECTED_LINE  Connected line has changed
  * \arg \b REDIRECTING     Call redirecting information has changed.
  */
@@ -323,6 +324,7 @@
 	AST_CONTROL_CONNECTED_LINE = 22,/*!< Indicate connected line has changed */
 	AST_CONTROL_REDIRECTING = 23,    /*!< Indicate redirecting id has changed */
 	AST_CONTROL_T38_PARAMETERS = 24, /*! T38 state change request/notification with parameters */
+	AST_CONTROL_SRCCHANGE = 25,  /*!< Media source has changed and requires a new RTP SSRC */
 };
 
 enum ast_control_t38 {

Modified: trunk/include/asterisk/rtp_engine.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/rtp_engine.h?view=diff&rev=252089&r1=252088&r2=252089
==============================================================================
--- trunk/include/asterisk/rtp_engine.h (original)
+++ trunk/include/asterisk/rtp_engine.h Fri Mar 12 16:04:51 2010
@@ -92,8 +92,6 @@
 	AST_RTP_PROPERTY_STUN,
 	/*! Enable RTCP support */
 	AST_RTP_PROPERTY_RTCP,
-	/*! Don't force a new SSRC on new source */
-	AST_RTP_PROPERTY_CONSTANT_SSRC,
 
 	/*!
 	 * \brief Maximum number of RTP properties supported
@@ -322,10 +320,10 @@
 	int (*dtmf_begin)(struct ast_rtp_instance *instance, char digit);
 	/*! Callback for stopping RFC2833 DTMF transmission */
 	int (*dtmf_end)(struct ast_rtp_instance *instance, char digit);
-	/*! Callback to indicate that a new source of media has come in */
-	void (*new_source)(struct ast_rtp_instance *instance);
-	/*! Callback to tell new_source not to change SSRC */
-	void (*constant_ssrc_set)(struct ast_rtp_instance *instance);
+	/*! Callback to indicate that we should update the marker bit */
+	void (*update_source)(struct ast_rtp_instance *instance);
+	/*! Callback to indicate that we should update the marker bit and ssrc */
+	void (*change_source)(struct ast_rtp_instance *instance);
 	/*! Callback for setting an extended RTP property */
 	int (*extended_prop_set)(struct ast_rtp_instance *instance, int property, void *value);
 	/*! Callback for getting an extended RTP property */
@@ -1192,22 +1190,40 @@
 enum ast_rtp_dtmf_mode ast_rtp_instance_dtmf_mode_get(struct ast_rtp_instance *instance);
 
 /*!
- * \brief Indicate a new source of audio has dropped in
+ * \brief Indicate that the RTP marker bit should be set on an RTP stream
  *
  * \param instance Instance that the new media source is feeding into
  *
  * Example usage:
  *
  * \code
- * ast_rtp_instance_new_source(instance);
- * \endcode
- *
- * This indicates that a new source of media is feeding the instance pointed to by
- * instance.
- *
- * \since 1.8
- */
-void ast_rtp_instance_new_source(struct ast_rtp_instance *instance);
+ * ast_rtp_instance_update_source(instance);
+ * \endcode
+ *
+ * This indicates that the source of media that is feeding the instance pointed to by
+ * instance has been updated and that the marker bit should be set.
+ *
+ * \since 1.8
+ */
+void ast_rtp_instance_update_source(struct ast_rtp_instance *instance);
+
+/*!
+ * \brief Indicate a new source of audio has dropped in and the ssrc should change
+ *
+ * \param instance Instance that the new media source is feeding into
+ *
+ * Example usage:
+ *
+ * \code
+ * ast_rtp_instance_change_source(instance);
+ * \endcode
+ *
+ * This indicates that the source of media that is feeding the instance pointed to by
+ * instance has changed and that the marker bit should be set and the SSRC updated.
+ *
+ * \since 1.8
+ */
+void ast_rtp_instance_change_source(struct ast_rtp_instance *instance);
 
 /*!
  * \brief Set QoS parameters on an RTP session

Modified: trunk/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/channel.c?view=diff&rev=252089&r1=252088&r2=252089
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Fri Mar 12 16:04:51 2010
@@ -2964,6 +2964,7 @@
 				case AST_CONTROL_RINGING:
 				case AST_CONTROL_ANSWER:
 				case AST_CONTROL_SRCUPDATE:
+				case AST_CONTROL_SRCCHANGE:
 				case AST_CONTROL_CONNECTED_LINE:
 				case AST_CONTROL_REDIRECTING:
 					/* Unimportant */
@@ -3599,6 +3600,7 @@
 	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:
@@ -3739,6 +3741,7 @@
 	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:
@@ -4474,6 +4477,7 @@
 				case AST_CONTROL_UNHOLD:
 				case AST_CONTROL_VIDUPDATE:
 				case AST_CONTROL_SRCUPDATE:
+				case AST_CONTROL_SRCCHANGE:
 				case AST_CONTROL_CONNECTED_LINE:
 				case AST_CONTROL_REDIRECTING:
 				case -1:			/* Ignore -- just stopping indications */
@@ -5724,6 +5728,7 @@
 			case AST_CONTROL_UNHOLD:
 			case AST_CONTROL_VIDUPDATE:
 			case AST_CONTROL_SRCUPDATE:
+			case AST_CONTROL_SRCCHANGE:
 				ast_indicate_data(other, f->subclass.integer, f->data.ptr, f->datalen);
 				if (jb_in_use) {
 					ast_jb_empty_and_reset(c0, c1);

Modified: trunk/main/rtp_engine.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/rtp_engine.c?view=diff&rev=252089&r1=252088&r2=252089
==============================================================================
--- trunk/main/rtp_engine.c (original)
+++ trunk/main/rtp_engine.c Fri Mar 12 16:04:51 2010
@@ -728,10 +728,17 @@
 	return instance->dtmf_mode;
 }
 
-void ast_rtp_instance_new_source(struct ast_rtp_instance *instance)
-{
-	if (instance->engine->new_source) {
-		instance->engine->new_source(instance);
+void ast_rtp_instance_update_source(struct ast_rtp_instance *instance)
+{
+	if (instance->engine->update_source) {
+		instance->engine->update_source(instance);
+	}
+}
+
+void ast_rtp_instance_change_source(struct ast_rtp_instance *instance)
+{
+	if (instance->engine->change_source) {
+		instance->engine->change_source(instance);
 	}
 }
 

Modified: trunk/res/res_rtp_asterisk.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_rtp_asterisk.c?view=diff&rev=252089&r1=252088&r2=252089
==============================================================================
--- trunk/res/res_rtp_asterisk.c (original)
+++ trunk/res/res_rtp_asterisk.c Fri Mar 12 16:04:51 2010
@@ -254,7 +254,8 @@
 static int ast_rtp_destroy(struct ast_rtp_instance *instance);
 static int ast_rtp_dtmf_begin(struct ast_rtp_instance *instance, char digit);
 static int ast_rtp_dtmf_end(struct ast_rtp_instance *instance, char digit);
-static void ast_rtp_new_source(struct ast_rtp_instance *instance);
+static void ast_rtp_update_source(struct ast_rtp_instance *instance);
+static void ast_rtp_change_source(struct ast_rtp_instance *instance);
 static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *frame);
 static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtcp);
 static void ast_rtp_prop_set(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value);
@@ -276,7 +277,8 @@
 	.destroy = ast_rtp_destroy,
 	.dtmf_begin = ast_rtp_dtmf_begin,
 	.dtmf_end = ast_rtp_dtmf_end,
-	.new_source = ast_rtp_new_source,
+	.update_source = ast_rtp_update_source,
+	.change_source = ast_rtp_change_source,
 	.write = ast_rtp_write,
 	.read = ast_rtp_read,
 	.prop_set = ast_rtp_prop_set,
@@ -655,16 +657,27 @@
 	return 0;
 }
 
-static void ast_rtp_new_source(struct ast_rtp_instance *instance)
+static void ast_rtp_update_source(struct ast_rtp_instance *instance)
 {
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 
 	/* We simply set this bit so that the next packet sent will have the marker bit turned on */
 	ast_set_flag(rtp, FLAG_NEED_MARKER_BIT);
-
-	if (!ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_CONSTANT_SSRC)) {
-		rtp->ssrc = ast_random();
-	}
+	ast_debug(3, "Setting the marker bit due to a source update\n");
+
+	return;
+}
+
+static void ast_rtp_change_source(struct ast_rtp_instance *instance)
+{
+	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+	unsigned int ssrc = ast_random();
+
+	/* We simply set this bit so that the next packet sent will have the marker bit turned on */
+	ast_set_flag(rtp, FLAG_NEED_MARKER_BIT);
+
+	ast_debug(3, "Changing ssrc from %u to %u due to a source change\n", rtp->ssrc, ssrc);
+	rtp->ssrc = ssrc;
 
 	return;
 }
@@ -1854,6 +1867,7 @@
 	unsigned int *rtpheader = (unsigned int*)(rtp->rawdata + AST_FRIENDLY_OFFSET), seqno, ssrc, timestamp;
 	struct ast_rtp_payload_type payload;
 	struct sockaddr_in remote_address = { 0, };
+	AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
 
 	/* If this is actually RTCP let's hop on over and handle it */
 	if (rtcp) {
@@ -1951,13 +1965,26 @@
 	timestamp = ntohl(rtpheader[1]);
 	ssrc = ntohl(rtpheader[2]);
 
-	/* Force a marker bit if the SSRC changes */
-	if (!mark && rtp->rxssrc && rtp->rxssrc != ssrc) {
-		if (option_debug || rtpdebug) {
-			ast_debug(1, "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.integer = AST_CONTROL_SRCCHANGE,
+		};
+
+		if (!mark) {
+			if (option_debug || rtpdebug) {
+				ast_debug(1, "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;
 
 	/* Remove any padding bytes that may be present */
 	if (padding) {
@@ -1986,7 +2013,7 @@
 	/* Make sure after we potentially mucked with the header length that it is once again valid */
 	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++;
@@ -2029,7 +2056,11 @@
 			ast_log(LOG_NOTICE, "Unknown RTP codec %d received from '%s'\n", payloadtype, ast_inet_ntoa(remote_address.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.codec = payload.code;
@@ -2046,7 +2077,8 @@
 			f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(f->subclass.codec)), 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);
 		}
 	}
 
@@ -2081,7 +2113,7 @@
 		rtp->f.subclass.codec = AST_FORMAT_T140;
 		header_end = memchr(data, ((*data) & 0x7f), rtp->f.datalen);
 		if (header_end == NULL) {
-			return &ast_null_frame;
+			return AST_LIST_FIRST(&frames) ? AST_LIST_FIRST(&frames) : &ast_null_frame;
 		}
 		header_end++;
 
@@ -2094,7 +2126,7 @@
 				len += data[x * 4 + 3];
 
 			if (!(rtp->f.datalen - len))
-				return &ast_null_frame;
+				return AST_LIST_FIRST(&frames) ? AST_LIST_FIRST(&frames) : &ast_null_frame;
 
 			rtp->f.data.ptr += len;
 			rtp->f.datalen -= len;
@@ -2150,7 +2182,8 @@
 		rtp->f.delivery.tv_usec = 0;
 	}
 
-	return &rtp->f;
+	AST_LIST_INSERT_TAIL(&frames, &rtp->f, frame_list);
+	return AST_LIST_FIRST(&frames);
 }
 
 static void ast_rtp_prop_set(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)




More information about the svn-commits mailing list