diff --git a/apps/app_controlplayback.c b/apps/app_controlplayback.c
index 089a7f4d8bf3dd965d8448eeeb8ce085c40cebee..850ebed9ccf470b2ea23928f13394781b2d1dc67 100755
--- a/apps/app_controlplayback.c
+++ b/apps/app_controlplayback.c
@@ -31,14 +31,13 @@ static char *app = "ControlPlayback";
 static char *synopsis = "Play a file with fast forward and rewind";
 
 static char *descrip = 
-"ControlPlayback(filename[|skipms]|[ffchar]|[rewchar]|[stopchar]]):\n"
+"ControlPlayback(filename[|skipms[|ffchar[|rewchar[|stopchar[|pausechr]]]]]):\n"
 "  Plays  back  a  given  filename (do not put extension). Options may also\n"
 "  be included following a pipe symbol.  You can use * and # to rewind and\n"
 "  fast forward the playback specified. If 'stopchar' is added the file will\n"
 "  terminate playback when 'stopchar' is pressed. Returns -1 if the channel\n"
 "  was hung up, or if the file does not exist. Returns 0 otherwise.\n\n"
-"  Example:  exten => 1234,1,ControlPlayback(file|4000|*|#|1)\n\n";
-
+"  Example:  exten => 1234,1,ControlPlayback(file|4000|*|#|1|0)\n\n";
 
 STANDARD_LOCAL_USER;
 
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index a9b75da33b34fc011effb6ddf3aa0b70444a9503..15c3f811b9da0074462733e8774ed44a9eb60c9a 100755
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -265,6 +265,7 @@ static struct sip_pvt {
 	struct sockaddr_in sa;			/* Our peer */
 	struct sockaddr_in redirip;		/* Where our RTP should be going if not to us */
 	struct sockaddr_in vredirip;		/* Where our Video RTP should be going if not to us */
+	int redircodecs;				/* Redirect codecs */
 	struct sockaddr_in recv;		/* Received as */
 	struct in_addr ourip;			/* Our IP */
 	struct ast_channel *owner;		/* Who owns us */
@@ -305,6 +306,7 @@ static struct sip_pvt {
 	char lastmsg[256];			/* Last Message sent/received */
 	int amaflags;				/* AMA Flags */
 	int pendinginvite;			/* Any pending invite */
+	int needreinvite;			/* Do we need to send another reinvite? */
 	int pendingbye;				/* Need to send bye after we ack? */
 	int gotrefer;				/* Got a refer? */
 	struct sip_request initreq;		/* Initial request */
@@ -493,7 +495,7 @@ static int transmit_response_with_auth(struct sip_pvt *p, char *msg, struct sip_
 static int transmit_request(struct sip_pvt *p, char *msg, int inc, int reliable, int newbranch);
 static int transmit_request_with_auth(struct sip_pvt *p, char *msg, int inc, int reliable, int newbranch);
 static int transmit_invite(struct sip_pvt *p, char *msg, int sendsdp, char *auth, char *authheader, char *vxml_url,char *distinctive_ring, int init);
-static int transmit_reinvite_with_sdp(struct sip_pvt *p, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codec);
+static int transmit_reinvite_with_sdp(struct sip_pvt *p);
 static int transmit_info_with_digit(struct sip_pvt *p, char digit);
 static int transmit_message_with_text(struct sip_pvt *p, char *text);
 static int transmit_refer(struct sip_pvt *p, char *dest);
@@ -1552,6 +1554,7 @@ static int sip_hangup(struct ast_channel *ast)
 				/* Note we will need a BYE when this all settles out
 				   but we can't send one while we have "INVITE" outstanding. */
 				p->pendingbye = 1;
+				p->needreinvite = 0;
 			}
 		}
 	}
@@ -3003,7 +3006,7 @@ static int add_digit(struct sip_request *req, char digit)
 }
 
 /*--- add_sdp: Add Session Description Protocol message ---*/
-static int add_sdp(struct sip_request *resp, struct sip_pvt *p, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs)
+static int add_sdp(struct sip_request *resp, struct sip_pvt *p)
 {
 	int len;
 	int codec;
@@ -3033,8 +3036,6 @@ static int add_sdp(struct sip_request *resp, struct sip_pvt *p, struct ast_rtp *
 		return -1;
 	}
 	capability = p->jointcapability;
-	if (codecs) 
-		capability = codecs & p->jointcapability;
 		
 	if (!p->sessionid) {
 		p->sessionid = getpid();
@@ -3048,8 +3049,8 @@ static int add_sdp(struct sip_request *resp, struct sip_pvt *p, struct ast_rtp *
 	if (p->redirip.sin_addr.s_addr) {
 		dest.sin_port = p->redirip.sin_port;
 		dest.sin_addr = p->redirip.sin_addr;
-	} else if (rtp) {
-		ast_rtp_get_peer(rtp, &dest);
+		if (p->redircodecs)
+			capability = p->redircodecs;
 	} else {
 		dest.sin_addr = p->ourip;
 		dest.sin_port = sin.sin_port;
@@ -3060,8 +3061,6 @@ static int add_sdp(struct sip_request *resp, struct sip_pvt *p, struct ast_rtp *
 		if (p->vredirip.sin_addr.s_addr) {
 			vdest.sin_port = p->vredirip.sin_port;
 			vdest.sin_addr = p->vredirip.sin_addr;
-		} else if (vrtp) {
-			ast_rtp_get_peer(vrtp, &vdest);
 		} else {
 			vdest.sin_addr = p->ourip;
 			vdest.sin_port = vsin.sin_port;
@@ -3210,7 +3209,7 @@ static int transmit_response_with_sdp(struct sip_pvt *p, char *msg, struct sip_r
 		return -1;
 	}
 	respprep(&resp, p, msg, req);
-	add_sdp(&resp, p, NULL, NULL, 0);
+	add_sdp(&resp, p);
 	return send_response(p, &resp, retrans, seqno);
 }
 
@@ -3277,7 +3276,7 @@ static int determine_firstline_parts( struct sip_request *req ) {
 /* transmit_reinvite_with_sdp: Transmit reinvite with SDP :-) ---*/
 /*   A re-invite is basically a new INVITE with the same CALL-ID and TAG as the
      INVITE that opened the SIP dialogue */
-static int transmit_reinvite_with_sdp(struct sip_pvt *p, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codec)
+static int transmit_reinvite_with_sdp(struct sip_pvt *p)
 {
 	struct sip_request req;
 	if (p->canreinvite == REINVITE_UPDATE)
@@ -3286,7 +3285,7 @@ static int transmit_reinvite_with_sdp(struct sip_pvt *p, struct ast_rtp *rtp, st
 		reqprep(&req, p, "INVITE", 0, 1);
 	
 	add_header(&req, "Allow", ALLOWED_METHODS);
-	add_sdp(&req, p, rtp, vrtp, codec);
+	add_sdp(&req, p);
 	/* Use this as the basis */
 	copy_request(&p->initreq, &req);
 	parse(&p->initreq);
@@ -3433,7 +3432,7 @@ static int transmit_invite(struct sip_pvt *p, char *cmd, int sdp, char *auth, ch
 	}
 	add_header(&req, "Allow", ALLOWED_METHODS);
 	if (sdp) {
-		add_sdp(&req, p, NULL, NULL, 0);
+		add_sdp(&req, p);
 	} else {
 		add_header(&req, "Content-Length", "0");
 		add_blank_header(&req);
@@ -5846,6 +5845,21 @@ static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req)
 		strncpy(p->owner->call_forward, s, sizeof(p->owner->call_forward) - 1);
 }
 
+static void check_pendings(struct sip_pvt *p)
+{
+	/* Go ahead and send bye at this point */
+	if (p->pendingbye) {
+		transmit_request_with_auth(p, "BYE", 0, 1, 1);
+		p->needdestroy = 1;
+		p->needreinvite = 0;
+	} else if (p->needreinvite) {
+		ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
+		/* Didn't get to reinvite yet, so do it now */
+		transmit_reinvite_with_sdp(p);
+		p->needreinvite = 0;
+	}
+}
+
 /*--- handle_response: Handle SIP response in dialogue ---*/
 static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore)
 {
@@ -5984,11 +5998,7 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
 				p->authtries = 0;
 				/* If I understand this right, the branch is different for a non-200 ACK only */
 				transmit_request(p, "ACK", seqno, 0, 1);
-				/* Go ahead and send bye at this point */
-				if (p->pendingbye) {
-					transmit_request_with_auth(p, "BYE", 0, 1, 1);
-					p->needdestroy = 1;
-				}
+				check_pendings(p);
 			} else if (!strcasecmp(msg, "REGISTER")) {
 				/* char *exp; */
 				int expires, expires_ms;
@@ -6342,6 +6352,8 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
 			sip_cancel_destroy(p);
 			/* This call is no longer outgoing if it ever was */
 			p->outgoing = 0;
+			/* This also counts as a pending invite */
+			p->pendinginvite = 1;
 			copy_request(&p->initreq, req);
 			check_via(p, req);
 			if (!ast_strlen_zero(get_header(req, "Content-Type"))) {
@@ -6681,11 +6693,13 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
 		/* Uhm, I haven't figured out the point of the ACK yet.  Are we
 		   supposed to retransmit responses until we get an ack? 
 		   Make sure this is on a valid call */
+		p->pendinginvite = 0;
 		__sip_ack(p, seqno, FLAG_RESPONSE);
 		if (!ast_strlen_zero(get_header(req, "Content-Type"))) {
 			if (process_sdp(p, req))
 				return -1;
 		} 
+		check_pendings(p);
 		if (!p->lastinvite && ast_strlen_zero(p->randdata))
 			p->needdestroy = 1;
 	} else if (!strcasecmp(cmd, "SIP/2.0")) {
@@ -7730,7 +7744,7 @@ static struct ast_rtp *sip_get_vrtp_peer(struct ast_channel *chan)
 	return NULL;
 }
 
-static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codec)
+static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs)
 {
 	struct sip_pvt *p;
 	p = chan->pvt->pvt;
@@ -7743,8 +7757,14 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struc
 			ast_rtp_get_peer(vrtp, &p->vredirip);
 		else
 			memset(&p->vredirip, 0, sizeof(p->vredirip));
+		p->redircodecs = codecs;
 		if (!p->gotrefer) {
-			transmit_reinvite_with_sdp(p, rtp, vrtp, codec);
+			if (!p->pendinginvite)
+				transmit_reinvite_with_sdp(p);
+			else if (!p->pendingbye) {
+				ast_log(LOG_DEBUG, "Deferring reinvite on '%s'\n", p->callid);
+				p->needreinvite = 1;
+			}
 			p->outgoing = 1;
 		}
 		return 0;
diff --git a/rtp.c b/rtp.c
index 12658cfe8468396f99fe9562c33353cc03abb29b..90c7d602236d75d2ffec32e5501797049c35146b 100755
--- a/rtp.c
+++ b/rtp.c
@@ -1264,14 +1264,6 @@ int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, st
 	memset(&vac0, 0, sizeof(vac0));
 	memset(&vac1, 0, sizeof(vac1));
 
-	/* XXX Wait a half a second for things to settle up 
-			this really should be fixed XXX */
-	ast_autoservice_start(c0);
-	ast_autoservice_start(c1);
-	usleep(500000);
-	ast_autoservice_stop(c0);
-	ast_autoservice_stop(c1);
-
 	/* if need DTMF, cant native bridge */
 	if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
 		return -2;